Beispiel #1
0
        public void Create_WhenCertificateNull_Throws()
        {
            var exception = Assert.Throws <ArgumentNullException>(
                () => SigningCertificateV2.Create(certificate: null, hashAlgorithmName: HashAlgorithmName.SHA256));

            Assert.Equal("certificate", exception.ParamName);
        }
Beispiel #2
0
        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);
                }
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        public void Create_WithValidInput_ReturnsSigningCertificateV2(HashAlgorithmName hashAlgorithmName)
        {
            using (var certificate = _fixture.GetDefaultCertificate())
            {
                var signingCertificateV2 = SigningCertificateV2.Create(certificate, hashAlgorithmName);

                Assert.Equal(1, signingCertificateV2.Certificates.Count);

                var essCertIdV2 = signingCertificateV2.Certificates[0];

                Assert.Equal(hashAlgorithmName, CryptoHashUtility.OidToHashAlgorithmName(essCertIdV2.HashAlgorithm.Algorithm.Value));
                Assert.Equal(SigningTestUtility.GetHash(certificate, hashAlgorithmName), essCertIdV2.CertificateHash);
                Assert.Equal(1, essCertIdV2.IssuerSerial.GeneralNames.Count);
                Assert.Equal(certificate.IssuerName.Name, essCertIdV2.IssuerSerial.GeneralNames[0].DirectoryName.Name);
                SigningTestUtility.VerifySerialNumber(certificate, essCertIdV2.IssuerSerial);
                Assert.Null(signingCertificateV2.Policies);
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        /// <summary>
        /// Create a signing-certificate-v2 from a certificate.
        /// </summary>
        /// <param name="certificate">The signing certificate.</param>
        /// <param name="hashAlgorithm">The hash algorithm for the signing-certificate-v2 attribute.</param>
        public static CryptographicAttributeObject CreateSigningCertificateV2(
            X509Certificate2 certificate,
            Common.HashAlgorithmName hashAlgorithm)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            var signingCertificateV2 = SigningCertificateV2.Create(certificate, hashAlgorithm);
            var bytes = signingCertificateV2.Encode();

            var data = new AsnEncodedData(Oids.SigningCertificateV2, bytes);

            return(new CryptographicAttributeObject(
                       new Oid(Oids.SigningCertificateV2),
                       new AsnEncodedDataCollection(data)));
        }
Beispiel #8
0
 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);
        }