Example #1
0
        public void CreateSign()
        {
            byte[] data = File.ReadAllBytes(Path.Combine(_settings.PackagePath, _manifestFilename));

            X509Certificate2 certificate       = new X509Certificate2(_settings.CertificatePath, _settings.CertificatePassword, X509KeyStorageFlags.Exportable);
            X509Certificate2 intermCertificate = new X509Certificate2(_settings.IntermCertificatePath);

            var privKey = SecurityUtils.GetRsaKeyPair(certificate.GetRSAPrivateKey()).Private;
            var cert    = SecurityUtils.FromX509Certificate(certificate);
            var interm  = SecurityUtils.FromX509Certificate(intermCertificate);

            CmsProcessableByteArray content   = new CmsProcessableByteArray(data);
            CmsSignedDataGenerator  generator = new CmsSignedDataGenerator();

            generator.AddSigner(privKey, cert, CmsSignedGenerator.EncryptionRsa, CmsSignedGenerator.DigestSha256);

            CmsSignedData signedContent = generator.Generate(content, false);
            var           si            = signedContent.GetSignerInfos();
            var           signer        = si.GetSigners().Cast <SignerInformation>().First();

            SignerInfo signerInfo = signer.ToSignerInfo();

            Asn1EncodableVector digestAlgorithmsVector = new Asn1EncodableVector();

            digestAlgorithmsVector.Add(new AlgorithmIdentifier(
                                           algorithm: new DerObjectIdentifier(_oidSHA256),
                                           parameters: DerNull.Instance));

            // Construct SignedData.encapContentInfo
            ContentInfo encapContentInfo = new ContentInfo(
                contentType: new DerObjectIdentifier(_oidPKCS7IdData),
                content: null);

            Asn1EncodableVector certificatesVector = new Asn1EncodableVector();

            certificatesVector.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetEncoded())));
            certificatesVector.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(interm.GetEncoded())));

            // Construct SignedData.signerInfos
            Asn1EncodableVector signerInfosVector = new Asn1EncodableVector();

            signerInfosVector.Add(signerInfo.ToAsn1Object());

            // Construct SignedData
            SignedData signedData = new SignedData(
                digestAlgorithms: new DerSet(digestAlgorithmsVector),
                contentInfo: encapContentInfo,
                certificates: new BerSet(certificatesVector),
                crls: null,
                signerInfos: new DerSet(signerInfosVector));

            ContentInfo contentInfo = new ContentInfo(
                contentType: new DerObjectIdentifier(_oidPKCS7IdSignedData),
                content: signedData);

            File.WriteAllBytes(Path.Combine(_settings.PackagePath, _signatureFilename), contentInfo.GetDerEncoded());
        }
Example #2
0
        /// <summary>
        /// Get a signature block that java will load a JAR with
        /// </summary>
        /// <param name="sfFileData">The data to sign</param>
        /// <returns>The signature block (including certificate) for the data passed in</returns>
        private byte[] SignIt(byte[] sfFileData)
        {
            AsymmetricKeyParameter privateKey = null;

            var cert = LoadCert(_pemData, out privateKey);

            //create things needed to make the CmsSignedDataGenerator work
            var certStore = X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(new List <X509Certificate>()
            {
                cert
            }));
            CmsSignedDataGenerator dataGen = new CmsSignedDataGenerator();

            dataGen.AddCertificates(certStore);
            dataGen.AddSigner(privateKey, cert, CmsSignedDataGenerator.EncryptionRsa, CmsSignedDataGenerator.DigestSha256);

            //content is detached- i.e. not included in the signature block itself
            CmsProcessableByteArray detachedContent = new CmsProcessableByteArray(sfFileData);
            var signedContent = dataGen.Generate(detachedContent, false);

            //do lots of stuff to get things in the proper ASN.1 structure for java to parse it properly.  much trial and error.
            var                 signerInfos            = signedContent.GetSignerInfos();
            var                 signer                 = signerInfos.GetSigners().Cast <SignerInformation>().First();
            SignerInfo          signerInfo             = signer.ToSignerInfo();
            Asn1EncodableVector digestAlgorithmsVector = new Asn1EncodableVector();

            digestAlgorithmsVector.Add(new AlgorithmIdentifier(new DerObjectIdentifier("2.16.840.1.101.3.4.2.1"), DerNull.Instance));
            ContentInfo         encapContentInfo = new ContentInfo(new DerObjectIdentifier("1.2.840.113549.1.7.1"), null);
            Asn1EncodableVector asnVector        = new Asn1EncodableVector();

            asnVector.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetEncoded())));
            Asn1EncodableVector signersVector = new Asn1EncodableVector();

            signersVector.Add(signerInfo.ToAsn1Object());
            SignedData  signedData  = new SignedData(new DerSet(digestAlgorithmsVector), encapContentInfo, new BerSet(asnVector), null, new DerSet(signersVector));
            ContentInfo contentInfo = new ContentInfo(new DerObjectIdentifier("1.2.840.113549.1.7.2"), signedData);

            return(contentInfo.GetDerEncoded());
        }
Example #3
0
        static void PKCS7()
        {
            GostCryptoConfig.ProviderType = ProviderTypes.VipNet;
            Config.InitCommon();

            BCX509.X509Certificate bcCert = null;
            using (var g = GostCryptoConfig.CreateGost3410AsymmetricAlgorithm())
            {
                bool   detached = false;
                byte[] data     = File.ReadAllBytes("test.xml");

                var certBytes = g.ContainerCertificateRaw;

                BCX509.X509CertificateParser _x509CertificateParser = new BCX509.X509CertificateParser();
                bcCert = _x509CertificateParser.ReadCertificate(certBytes);

                ICollection <BCX509.X509Certificate> certPath = new List <BCX509.X509Certificate>();
                certPath.Add(bcCert);

                IDigest digest  = new Gost3411Digest();
                string  hashOid = GostCryptoConfig.DefaultHashOid;

                byte[] dataHash = ComputeDigest(digest, data);

                // Construct SignerInfo.signedAttrs
                Asn1EncodableVector signedAttributesVector = new Asn1EncodableVector();

                // Add PKCS#9 contentType signed attribute
                signedAttributesVector.Add(
                    new Org.BouncyCastle.Asn1.Cms.Attribute(
                        new DerObjectIdentifier("1.2.840.113549.1.9.3"),
                        new DerSet(new DerObjectIdentifier("1.2.840.113549.1.7.1"))));

                // Add PKCS#9 messageDigest signed attribute
                signedAttributesVector.Add(
                    new Org.BouncyCastle.Asn1.Cms.Attribute(
                        new DerObjectIdentifier("1.2.840.113549.1.9.4"),
                        new DerSet(new DerOctetString(dataHash))));

                // Add PKCS#9 signingTime signed attribute
                signedAttributesVector.Add(
                    new Org.BouncyCastle.Asn1.Cms.Attribute(
                        new DerObjectIdentifier("1.2.840.113549.1.9.5"),
                        new DerSet(new Org.BouncyCastle.Asn1.Cms.Time(new DerUtcTime(DateTime.UtcNow)))));

                DerSet signedAttributes = new DerSet(signedAttributesVector);
                byte[] pkcs1Digest      = ComputeDigest(digest, signedAttributes.GetDerEncoded());
                byte[] pkcs1DigestInfo  = CreateDigestInfo(pkcs1Digest, hashOid);

                // hash


                //var signature = g.CreateSignature(hash);
                var formatter = new GostSignatureFormatter(g);
                var signature = formatter.CreateSignature(pkcs1Digest);

                // Construct SignerInfo
                SignerInfo signerInfo = new SignerInfo(
                    new SignerIdentifier(new IssuerAndSerialNumber(bcCert.IssuerDN, bcCert.SerialNumber)),
                    new AlgorithmIdentifier(new DerObjectIdentifier(hashOid), null),
                    signedAttributes,
                    new AlgorithmIdentifier(new DerObjectIdentifier(GostCryptoConfig.DefaultSignOid), null),
                    new DerOctetString(signature),
                    null);

                // Construct SignedData.digestAlgorithms
                Asn1EncodableVector digestAlgorithmsVector = new Asn1EncodableVector();
                digestAlgorithmsVector.Add(new AlgorithmIdentifier(new DerObjectIdentifier(hashOid), null));

                // Construct SignedData.encapContentInfo
                ContentInfo encapContentInfo = new ContentInfo(
                    new DerObjectIdentifier("1.2.840.113549.1.7.1"),
                    (detached) ? null : new DerOctetString(data));

                // Construct SignedData.certificates
                Asn1EncodableVector certificatesVector = new Asn1EncodableVector();
                foreach (BCX509.X509Certificate cert in certPath)
                {
                    certificatesVector.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetEncoded())));
                }

                // Construct SignedData.signerInfos
                Asn1EncodableVector signerInfosVector = new Asn1EncodableVector();
                signerInfosVector.Add(signerInfo.ToAsn1Object());

                // Construct SignedData
                SignedData signedData = new SignedData(
                    new DerSet(digestAlgorithmsVector),
                    encapContentInfo,
                    new BerSet(certificatesVector),
                    null,
                    new DerSet(signerInfosVector));

                // Construct top level ContentInfo
                ContentInfo contentInfo = new ContentInfo(
                    new DerObjectIdentifier("1.2.840.113549.1.7.2"),
                    signedData);

                var res = contentInfo.GetDerEncoded();
                File.WriteAllBytes("test.p7", res);


                CmsSignedData cms = new CmsSignedData(res);

                var certStore = cms.GetCertificates("Collection");


                SignerInformationStore signers = cms.GetSignerInfos();
                var it = signers.GetSigners().GetEnumerator();
                it.MoveNext();
                var signer = it.Current as SignerInformation;

                var b = signer.Verify(bcCert);
            }
        }
Example #4
0
        /// <summary>
        /// Формирование сигнатуры для серверной подписи
        /// </summary>
        /// <param name="alg"></param>
        /// <param name="data"></param>
        /// <param name="detached"></param>
        /// <returns></returns>
        public static byte[] ComputeSignature(Gost3410 alg, byte[] data, bool detached = true)
        {
            var certBytes = alg.ContainerCertificateRaw;

            var _x509CertificateParser = new BCX509.X509CertificateParser();
            var bcCert = _x509CertificateParser.ReadCertificate(certBytes);

            ICollection <BCX509.X509Certificate> certPath = new List <BCX509.X509Certificate>();

            certPath.Add(bcCert);

            IDigest digest;
            string  hashOid;
            string  signOid;

            if (GostCryptoConfig.ProviderType == ProviderTypes.CryptoPro256)
            {
                digest  = new GOST3411_2012_256Digest();
                signOid = Constants.OID_GR3410_12_256;
                hashOid = Constants.OID_GR3411_12_256;
            }
            else if (GostCryptoConfig.ProviderType == ProviderTypes.CryptoPro512)
            {
                digest  = new GOST3411_2012_512Digest();
                signOid = Constants.OID_GR3410_12_512;
                hashOid = Constants.OID_GR3411_12_512;
            }
            else
            {
                digest  = new Gost3411Digest();
                signOid = Constants.OID_GR3410_2001;
                hashOid = Constants.OID_GR3411_2001;
            }

            byte[] dataHash = ComputeDigest(digest, data);

            // Construct SignerInfo.signedAttrs
            Asn1EncodableVector signedAttributesVector = new Asn1EncodableVector();

            // Add PKCS#9 contentType signed attribute
            signedAttributesVector.Add(
                new Org.BouncyCastle.Asn1.Cms.Attribute(
                    new DerObjectIdentifier(Constants.szOID_RSA_contentType),
                    new DerSet(new DerObjectIdentifier(Constants.szOID_RSA_data))));

            // Add PKCS#9 messageDigest signed attribute
            signedAttributesVector.Add(
                new Org.BouncyCastle.Asn1.Cms.Attribute(
                    new DerObjectIdentifier(Constants.szOID_RSA_messageDigest),
                    new DerSet(new DerOctetString(dataHash))));

            // Add PKCS#9 signingTime signed attribute
            signedAttributesVector.Add(
                new Org.BouncyCastle.Asn1.Cms.Attribute(
                    new DerObjectIdentifier(Constants.szOID_RSA_signingTime),
                    new DerSet(new Org.BouncyCastle.Asn1.Cms.Time(new DerUtcTime(DateTime.UtcNow)))));

            DerSet signedAttributes = new DerSet(signedAttributesVector);

            byte[] pkcs1Digest = ComputeDigest(digest, signedAttributes.GetDerEncoded());
            //byte[] pkcs1DigestInfo = CreateDigestInfo(pkcs1Digest, hashOid);

            var formatter = new GostSignatureFormatter(alg);
            var signature = formatter.CreateSignature(pkcs1Digest);

            // Construct SignerInfo
            SignerInfo signerInfo = new SignerInfo(
                new SignerIdentifier(new IssuerAndSerialNumber(bcCert.IssuerDN, bcCert.SerialNumber)),
                new AlgorithmIdentifier(new DerObjectIdentifier(hashOid), null),
                signedAttributes,
                new AlgorithmIdentifier(new DerObjectIdentifier(signOid), null),
                new DerOctetString(signature),
                null);

            // Construct SignedData.digestAlgorithms
            Asn1EncodableVector digestAlgorithmsVector = new Asn1EncodableVector();

            digestAlgorithmsVector.Add(new AlgorithmIdentifier(new DerObjectIdentifier(hashOid), null));

            // Construct SignedData.encapContentInfo
            ContentInfo encapContentInfo = new ContentInfo(
                new DerObjectIdentifier(Constants.szOID_RSA_data),
                (detached) ? null : new DerOctetString(data));

            // Construct SignedData.certificates
            Asn1EncodableVector certificatesVector = new Asn1EncodableVector();

            foreach (BCX509.X509Certificate cert in certPath)
            {
                certificatesVector.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetEncoded())));
            }

            // Construct SignedData.signerInfos
            Asn1EncodableVector signerInfosVector = new Asn1EncodableVector();

            signerInfosVector.Add(signerInfo.ToAsn1Object());

            // Construct SignedData
            SignedData signedData = new SignedData(
                new DerSet(digestAlgorithmsVector),
                encapContentInfo,
                new BerSet(certificatesVector),
                null,
                new DerSet(signerInfosVector));

            // Construct top level ContentInfo
            ContentInfo contentInfo = new ContentInfo(
                new DerObjectIdentifier(Constants.szOID_RSA_signedData),
                signedData);

            return(contentInfo.GetDerEncoded());
        }
Example #5
0
        public byte[] GenerateP7s(byte[] data, X509Certificate signingCertificate, IEnumerable <X509Certificate> certPath)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (signingCertificate == null)
            {
                throw new ArgumentNullException(nameof(signingCertificate));
            }

            if (certPath == null)
            {
                throw new ArgumentNullException(nameof(certPath));
            }

            byte[] dataHashSha256 = this.ComputeHash(data);
            Asn1EncodableVector signedAttributesVector = this.CreateSignatureAttribute(dataHashSha256, signingCertificate);

            DerSet signedAttributes = new DerSet(signedAttributesVector);

            byte[] signedAttributesDigest = this.ComputeHash(signedAttributes.GetDerEncoded());

            byte[]              signature                = this.cadesExternalSignature.SignSha256(signedAttributesDigest);
            DerOctetString      digestSignature          = new DerOctetString(signature);
            AlgorithmIdentifier digestSignatureAlgorithm = this.CreateSignatureInfo();

            SignerInfo signerInfo = new SignerInfo(
                sid: new SignerIdentifier(new IssuerAndSerialNumber(signingCertificate.IssuerDN, signingCertificate.SerialNumber)),
                digAlgorithm: new AlgorithmIdentifier(
                    algorithm: new DerObjectIdentifier(Oid.SHA256),
                    parameters: DerNull.Instance
                    ),
                authenticatedAttributes: signedAttributes,
                digEncryptionAlgorithm: digestSignatureAlgorithm,
                encryptedDigest: digestSignature,
                unauthenticatedAttributes: null
                );

            // Construct SignedData.digestAlgorithms
            Asn1EncodableVector digestAlgorithmsVector = new Asn1EncodableVector();

            digestAlgorithmsVector.Add(
                new AlgorithmIdentifier(
                    algorithm: new DerObjectIdentifier(Oid.SHA256),
                    parameters: DerNull.Instance));

            // Construct SignedData.encapContentInfo
            ContentInfo encapContentInfo = new ContentInfo(
                contentType: new DerObjectIdentifier(Oid.PKCS7IdData),
                content: null);

            // Construct SignedData.certificates
            Asn1EncodableVector certificatesVector = new Asn1EncodableVector();

            foreach (X509Certificate cert in certPath)
            {
                certificatesVector.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetEncoded())));
            }

            // Construct SignedData.signerInfos
            Asn1EncodableVector signerInfosVector = new Asn1EncodableVector();

            signerInfosVector.Add(signerInfo.ToAsn1Object());

            // Construct SignedData
            SignedData signedData = new SignedData(
                digestAlgorithms: new DerSet(digestAlgorithmsVector),
                contentInfo: encapContentInfo,
                certificates: new BerSet(certificatesVector),
                crls: null,
                signerInfos: new DerSet(signerInfosVector));

            // Construct top level ContentInfo
            ContentInfo contentInfo = new ContentInfo(
                contentType: new DerObjectIdentifier(Oid.PKCS7IdSignedData),
                content: signedData);

            return(contentInfo.GetDerEncoded());
        }
Example #6
0
        /// <summary>
        /// Generates PKCS#7 signature of specified data
        /// </summary>
        /// <param name="data">Data to be signed</param>
        /// <param name="detached">Flag indicating whether detached signature should be produced</param>
        /// <param name="signingCertificate">Signing certificate</param>
        /// <param name="certPath">Certification path for signing certificate</param>
        /// <returns>DER encoded PKCS#7 signature of specified data</returns>
        public byte[] GenerateSignature(byte[] data, bool detached, BCX509.X509Certificate signingCertificate, ICollection <BCX509.X509Certificate> certPath)
        {
            if (this._disposed)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }

            string  hashOid       = HashAlgorithmUtils.GetHashOid(_hashAlgorihtm);
            IDigest hashGenerator = HashAlgorithmUtils.GetHashGenerator(_hashAlgorihtm);

            // Compute hash of input data
            byte[] dataHash = ComputeDigest(hashGenerator, data);

            // Construct SignerInfo.signedAttrs
            Asn1EncodableVector signedAttributesVector = new Asn1EncodableVector();

            // Add PKCS#9 contentType signed attribute
            signedAttributesVector.Add(
                new Org.BouncyCastle.Asn1.Cms.Attribute(
                    attrType: new DerObjectIdentifier(OID.PKCS9AtContentType),
                    attrValues: new DerSet(new DerObjectIdentifier(OID.PKCS7IdData))));

            // Add PKCS#9 messageDigest signed attribute
            signedAttributesVector.Add(
                new Org.BouncyCastle.Asn1.Cms.Attribute(
                    attrType: new DerObjectIdentifier(OID.PKCS9AtMessageDigest),
                    attrValues: new DerSet(new DerOctetString(dataHash))));

            // Add PKCS#9 signingTime signed attribute
            signedAttributesVector.Add(
                new Org.BouncyCastle.Asn1.Cms.Attribute(
                    attrType: new DerObjectIdentifier(OID.PKCS9AtSigningTime),
                    attrValues: new DerSet(new Org.BouncyCastle.Asn1.Cms.Time(new DerUtcTime(DateTime.UtcNow)))));

            // Compute digest of SignerInfo.signedAttrs
            DerSet signedAttributes = new DerSet(signedAttributesVector);

            byte[] signedAttributesDigest = ComputeDigest(hashGenerator, signedAttributes.GetDerEncoded());

            // Sign digest of SignerInfo.signedAttrs with private key stored on PKCS#11 compatible device
            Asn1OctetString     digestSignature          = null;
            AlgorithmIdentifier digestSignatureAlgorithm = null;

            if (_signatureScheme == SignatureScheme.RSASSA_PKCS1_v1_5)
            {
                // Construct DigestInfo
                byte[] digestInfo = CreateDigestInfo(signedAttributesDigest, hashOid);

                // Sign DigestInfo with CKM_RSA_PKCS mechanism
                byte[] signature = null;

                using (Session session = _slot.OpenSession(SessionType.ReadOnly))
                    using (Mechanism mechanism = new Mechanism(CKM.CKM_RSA_PKCS))
                        signature = session.Sign(mechanism, _privateKeyHandle, digestInfo);

                // Construct SignerInfo.signature
                digestSignature = new DerOctetString(signature);

                // Construct SignerInfo.signatureAlgorithm
                digestSignatureAlgorithm = new AlgorithmIdentifier(
                    algorithm: new DerObjectIdentifier(OID.PKCS1RsaEncryption),
                    parameters: DerNull.Instance
                    );
            }
            else if (_signatureScheme == SignatureScheme.RSASSA_PSS)
            {
                // Construct parameters for CKM_RSA_PKCS_PSS mechanism
                CkRsaPkcsPssParams pssMechanismParams = CreateCkRsaPkcsPssParams(_hashAlgorihtm);

                // Sign digest with CKM_RSA_PKCS_PSS mechanism
                byte[] signature = null;

                using (Session session = _slot.OpenSession(SessionType.ReadOnly))
                    using (Mechanism mechanism = new Mechanism(CKM.CKM_RSA_PKCS_PSS, pssMechanismParams))
                        signature = session.Sign(mechanism, _privateKeyHandle, signedAttributesDigest);

                // Construct SignerInfo.signature
                digestSignature = new DerOctetString(signature);

                // Construct SignerInfo.signatureAlgorithm
                digestSignatureAlgorithm = new AlgorithmIdentifier(
                    algorithm: new DerObjectIdentifier(OID.PKCS1RsassaPss),
                    parameters: new Org.BouncyCastle.Asn1.Pkcs.RsassaPssParameters(
                        hashAlgorithm: new AlgorithmIdentifier(
                            algorithm: new DerObjectIdentifier(hashOid),
                            parameters: DerNull.Instance
                            ),
                        maskGenAlgorithm: new AlgorithmIdentifier(
                            algorithm: new DerObjectIdentifier(OID.PKCS1Mgf1),
                            parameters: new AlgorithmIdentifier(
                                algorithm: new DerObjectIdentifier(hashOid),
                                parameters: DerNull.Instance
                                )
                            ),
                        saltLength: new DerInteger(hashGenerator.GetDigestSize()),
                        trailerField: new DerInteger(1)
                        )
                    );
            }
            else
            {
                throw new NotSupportedException("Unsupported signature scheme");
            }

            // Construct SignerInfo
            SignerInfo signerInfo = new SignerInfo(
                sid: new SignerIdentifier(new IssuerAndSerialNumber(signingCertificate.IssuerDN, signingCertificate.SerialNumber)),
                digAlgorithm: new AlgorithmIdentifier(
                    algorithm: new DerObjectIdentifier(hashOid),
                    parameters: DerNull.Instance
                    ),
                authenticatedAttributes: signedAttributes,
                digEncryptionAlgorithm: digestSignatureAlgorithm,
                encryptedDigest: digestSignature,
                unauthenticatedAttributes: null
                );

            // Construct SignedData.digestAlgorithms
            Asn1EncodableVector digestAlgorithmsVector = new Asn1EncodableVector();

            digestAlgorithmsVector.Add(
                new AlgorithmIdentifier(
                    algorithm: new DerObjectIdentifier(hashOid),
                    parameters: DerNull.Instance));

            // Construct SignedData.encapContentInfo
            ContentInfo encapContentInfo = new ContentInfo(
                contentType: new DerObjectIdentifier(OID.PKCS7IdData),
                content: (detached) ? null : new DerOctetString(data));

            // Construct SignedData.certificates
            Asn1EncodableVector certificatesVector = new Asn1EncodableVector();

            foreach (BCX509.X509Certificate cert in certPath)
            {
                certificatesVector.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetEncoded())));
            }

            // Construct SignedData.signerInfos
            Asn1EncodableVector signerInfosVector = new Asn1EncodableVector();

            signerInfosVector.Add(signerInfo.ToAsn1Object());

            // Construct SignedData
            SignedData signedData = new SignedData(
                digestAlgorithms: new DerSet(digestAlgorithmsVector),
                contentInfo: encapContentInfo,
                certificates: new BerSet(certificatesVector),
                crls: null,
                signerInfos: new DerSet(signerInfosVector));

            // Construct top level ContentInfo
            ContentInfo contentInfo = new ContentInfo(
                contentType: new DerObjectIdentifier(OID.PKCS7IdSignedData),
                content: signedData);

            return(contentInfo.GetDerEncoded());
        }
Example #7
0
        /// <summary>
        /// Signs the signature file's content using the given certificate, and returns the RSA signature.
        /// </summary>
        /// <param name="signatureFileData">Content of the signature file to be signed</param>
        /// <param name="pemCertData">PEM data of the certificate and private key for signing</param>
        /// <returns>The RSA signature</returns>
        private byte[] GetSignature(byte[] signatureFileData, string pemCertData)
        {
            var(cert, privateKey) = LoadCertificate(pemCertData);

            var certStore = X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(new List <X509Certificate> {
                cert
            }));
            CmsSignedDataGenerator dataGen = new();

            dataGen.AddCertificates(certStore);
            dataGen.AddSigner(privateKey, cert, CmsSignedGenerator.EncryptionRsa, CmsSignedGenerator.DigestSha256);

            // Content is detached - i.e. not included in the signature block itself
            CmsProcessableByteArray detachedContent = new(signatureFileData);
            var signedContent = dataGen.Generate(detachedContent, false);

            // Get the signature in the proper ASN.1 structure for java to parse it properly.  Lots of trial and error
            var                 signerInfos            = signedContent.GetSignerInfos();
            var                 signer                 = signerInfos.GetSigners().Cast <SignerInformation>().First();
            SignerInfo          signerInfo             = signer.ToSignerInfo();
            Asn1EncodableVector digestAlgorithmsVector = new();

            digestAlgorithmsVector.Add(new AlgorithmIdentifier(new DerObjectIdentifier("2.16.840.1.101.3.4.2.1"), DerNull.Instance));
            ContentInfo         encapContentInfo = new(new DerObjectIdentifier("1.2.840.113549.1.7.1"), null);
            Asn1EncodableVector asnVector        = new()
            {
                X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetEncoded()))
            };
            Asn1EncodableVector signersVector = new() { signerInfo.ToAsn1Object() };
            SignedData          signedData    = new(new DerSet(digestAlgorithmsVector), encapContentInfo, new BerSet(asnVector), null, new DerSet(signersVector));
            ContentInfo         contentInfo   = new(new DerObjectIdentifier("1.2.840.113549.1.7.2"), signedData);

            return(contentInfo.GetDerEncoded());
        }

        /// <summary>
        /// Loads the certificate and private key from the given PEM data
        /// </summary>
        /// <param name="pemData"></param>
        /// <returns>The loaded certificate and private key</returns>
        /// <exception cref="System.Security.SecurityException">If the certificate or private key failed to load</exception>
        private (X509Certificate certificate, AsymmetricKeyParameter privateKey) LoadCertificate(string pemData)
        {
            X509Certificate?       cert       = null;
            AsymmetricKeyParameter?privateKey = null;

            using (var reader = new StringReader(pemData))
            {
                // Iterate through the PEM objects until we find the public or private key
                var    pemReader = new PemReader(reader);
                object pemObject;
                while ((pemObject = pemReader.ReadObject()) != null)
                {
                    cert ??= pemObject as X509Certificate;
                    privateKey ??= (pemObject as AsymmetricCipherKeyPair)?.Private;
                }
            }
            if (cert == null)
            {
                throw new System.Security.SecurityException("Certificate could not be loaded from PEM data.");
            }

            if (privateKey == null)
            {
                throw new System.Security.SecurityException("Private Key could not be loaded from PEM data.");
            }

            return(cert, privateKey);
        }