public void TestKeyTransSmallAesUsingAoepMixedParams()
        {
            byte[] data = new byte[] { 0, 1, 2, 3 };

            CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();

            edGen.AddRecipientInfoGenerator(
                new KeyTransRecipientInfoGenerator(
                    ReciCert,
                    new Asn1KeyWrapper(
                        PkcsObjectIdentifiers.IdRsaesOaep,
                        new RsaesOaepParameters(
                            new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance),
                            new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance))),
                        ReciCert)));

            CmsEnvelopedData ed = edGen.Generate(
                new CmsProcessableByteArray(data),
                CmsEnvelopedDataGenerator.Aes128Cbc);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            Assert.AreEqual(ed.EncryptionAlgOid,
                            CmsEnvelopedDataGenerator.Aes128Cbc);

            ICollection c = recipients.GetRecipients();

            Assert.AreEqual(1, c.Count);

            foreach (RecipientInformation recipient in c)
            {
                byte[] recData = recipient.GetContent(ReciKP.Private);
                Assert.IsTrue(Arrays.AreEqual(data, recData));
            }
        }
Example #2
0
        private void TryKeyTrans(
            string generatorOID,
            DerObjectIdentifier checkOID,
            Type asn1Params)
        {
            byte[] data = Encoding.ASCII.GetBytes("WallaWallaWashington");

            CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();

            edGen.AddKeyTransRecipient(ReciCert);

            CmsEnvelopedData ed = edGen.Generate(new CmsProcessableByteArray(data), generatorOID);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            Assert.AreEqual(checkOID.Id, ed.EncryptionAlgOid);

            if (asn1Params != null)
            {
                Assert.IsTrue(asn1Params.IsInstanceOfType(ed.EncryptionAlgorithmID.Parameters));
            }

            ArrayList c = new ArrayList(recipients.GetRecipients());

            Assert.AreEqual(1, c.Count);

            foreach (RecipientInformation recipient in c)
            {
                Assert.AreEqual(recipient.KeyEncryptionAlgOid, PkcsObjectIdentifiers.RsaEncryption.Id);

                byte[] recData = recipient.GetContent(ReciKP.Private);

                Assert.IsTrue(Arrays.AreEqual(data, recData));
            }
        }
Example #3
0
        public void TestErroneousKek()
        {
            byte[]       data = Encoding.ASCII.GetBytes("WallaWallaWashington");
            KeyParameter kek  = ParameterUtilities.CreateKeyParameter(
                "AES",
                new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 });

            CmsEnvelopedData ed = new CmsEnvelopedData(oldKEK);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.DesEde3Cbc);

            ICollection c = recipients.GetRecipients();

            Assert.AreEqual(1, c.Count);

            foreach (RecipientInformation recipient in c)
            {
                Assert.AreEqual(recipient.KeyEncryptionAlgOid, NistObjectIdentifiers.IdAes128Wrap.Id);

                byte[] recData = recipient.GetContent(kek);

                Assert.IsTrue(Arrays.AreEqual(data, recData));
            }
        }
Example #4
0
        private void PasswordUtf8Test(
            string algorithm)
        {
            byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");

            CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();

            edGen.AddPasswordRecipient(
                new Pkcs5Scheme2Utf8PbeKey("abc\u5639\u563b".ToCharArray(), new byte[20], 5),
                algorithm);

            CmsEnvelopedData ed = edGen.Generate(
                new CmsProcessableByteArray(data),
                CmsEnvelopedDataGenerator.Aes128Cbc);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.Aes128Cbc);

            ICollection c = recipients.GetRecipients();

            Assert.AreEqual(1, c.Count);

            foreach (PasswordRecipientInformation recipient in c)
            {
                CmsPbeKey key = new Pkcs5Scheme2Utf8PbeKey(
                    "abc\u5639\u563b".ToCharArray(), recipient.KeyDerivationAlgorithm);

                byte[] recData = recipient.GetContent(key);

                Assert.IsTrue(Arrays.AreEqual(data, recData));
            }
        }
Example #5
0
        private void VerifyECMqvKeyAgreeVectors(
            AsymmetricKeyParameter privKey,
            string wrapAlg,
            byte[]                                  message)
        {
            byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");

            CmsEnvelopedData ed = new CmsEnvelopedData(message);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            ICollection c = recipients.GetRecipients();

            Assert.AreEqual(wrapAlg, ed.EncryptionAlgOid);
            Assert.AreEqual(1, c.Count);

            foreach (RecipientInformation recipient in c)
            {
                Assert.AreEqual("1.3.133.16.840.63.0.16", recipient.KeyEncryptionAlgOid);

                byte[] recData = recipient.GetContent(privKey);

                Assert.IsTrue(Arrays.AreEqual(data, recData));
            }
        }
Example #6
0
        public void TestECMqvKeyAgreeMultiple()
        {
            byte[] data = Hex.Decode("504b492d4320434d5320456e76656c6f706564446174612053616d706c65");

            CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();

            ArrayList recipientCerts = new ArrayList();

            recipientCerts.Add(ReciECCert);
            recipientCerts.Add(ReciECCert2);

            edGen.AddKeyAgreementRecipients(
                CmsEnvelopedDataGenerator.ECMqvSha1Kdf,
                OrigECKP.Private,
                OrigECKP.Public,
                recipientCerts,
                CmsEnvelopedDataGenerator.Aes128Wrap);

            CmsEnvelopedData ed = edGen.Generate(
                new CmsProcessableByteArray(data),
                CmsEnvelopedDataGenerator.Aes128Cbc);

            Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.Aes128Cbc);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            ConfirmDataReceived(recipients, data, ReciECCert, ReciECKP.Private);
            ConfirmDataReceived(recipients, data, ReciECCert2, ReciECKP2.Private);
            ConfirmNumberRecipients(recipients, 2);
        }
Example #7
0
        public void TestRfc4134Ex5_1()
        {
            byte[] data = Hex.Decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e");

//			KeyFactory kFact = KeyFactory.GetInstance("RSA");
//			Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt));
            AsymmetricKeyParameter key = PrivateKeyFactory.CreateKey(bobPrivRsaEncrypt);

            CmsEnvelopedData ed = new CmsEnvelopedData(rfc4134ex5_1);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            Assert.AreEqual("1.2.840.113549.3.7", ed.EncryptionAlgOid);

            ICollection c = recipients.GetRecipients();

            Assert.AreEqual(1, c.Count);

            foreach (RecipientInformation recipient in c)
            {
                byte[] recData = recipient.GetContent(key);

                Assert.IsTrue(Arrays.AreEqual(data, recData));
            }
        }
        public void TestKeyTransSmallAesUsingAoepMixed()
        {
            byte[] data = new byte[] { 0, 1, 2, 3 };

            CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();

            edGen.AddRecipientInfoGenerator(new KeyTransRecipientInfoGenerator(ReciCert, new Asn1KeyWrapper("RSA/None/OAEPwithSHA256andMGF1withSHA1Padding", ReciCert)));

            CmsEnvelopedData ed = edGen.Generate(
                new CmsProcessableByteArray(data),
                CmsEnvelopedDataGenerator.Aes128Cbc);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            Assert.AreEqual(ed.EncryptionAlgOid,
                            CmsEnvelopedDataGenerator.Aes128Cbc);

            ICollection c = recipients.GetRecipients();

            Assert.AreEqual(1, c.Count);

            foreach (RecipientInformation recipient in c)
            {
                byte[] recData = recipient.GetContent(ReciKP.Private);
                Assert.IsTrue(Arrays.AreEqual(data, recData));
            }
        }
Example #9
0
        private void TryKekAlgorithm(
            KeyParameter kek,
            DerObjectIdentifier algOid)
        {
            byte[] data = Encoding.ASCII.GetBytes("WallaWallaWashington");
            CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();

            byte[] kekId = new byte[] { 1, 2, 3, 4, 5 };

            string keyAlgorithm = ParameterUtilities.GetCanonicalAlgorithmName(algOid.Id);

            edGen.AddKekRecipient(keyAlgorithm, kek, kekId);

            CmsEnvelopedData ed = edGen.Generate(
                new CmsProcessableByteArray(data),
                CmsEnvelopedDataGenerator.DesEde3Cbc);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedDataGenerator.DesEde3Cbc);

            ArrayList c = new ArrayList(recipients.GetRecipients());

            Assert.IsTrue(c.Count > 0);

            foreach (RecipientInformation recipient in c)
            {
                Assert.AreEqual(algOid.Id, recipient.KeyEncryptionAlgOid);

                byte[] recData = recipient.GetContent(kek);

                Assert.IsTrue(Arrays.AreEqual(data, recData));
            }
        }
Example #10
0
        public void TestKeyTransSmallAes()
        {
            byte[] data = new byte[] { 0, 1, 2, 3 };

            CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();

            edGen.AddKeyTransRecipient(ReciCert);

            CmsEnvelopedData ed = edGen.Generate(
                new CmsProcessableByteArray(data),
                CmsEnvelopedDataGenerator.Aes128Cbc);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            Assert.AreEqual(ed.EncryptionAlgOid,
                            CmsEnvelopedDataGenerator.Aes128Cbc);

            ICollection c = recipients.GetRecipients();

            Assert.AreEqual(1, c.Count);

            foreach (RecipientInformation recipient in c)
            {
                byte[] recData = recipient.GetContent(ReciKP.Private);
                Assert.IsTrue(Arrays.AreEqual(data, recData));
            }
        }
Example #11
0
        internal static byte[] FetchEnvelopedData(ICipherParameters certificateKey, X509Certificate certificate, PdfArray recipients)
        {
            bool foundRecipient = false;

            byte[] envelopedData = null;
            for (int i = 0; i < recipients.Size(); i++)
            {
                try {
                    PdfString        recipient = recipients.GetAsString(i);
                    CmsEnvelopedData data      = new CmsEnvelopedData(recipient.GetValueBytes());

                    foreach (RecipientInformation recipientInfo in data.GetRecipientInfos().GetRecipients())
                    {
                        if (recipientInfo.RecipientID.Match(certificate) && !foundRecipient)
                        {
                            envelopedData  = recipientInfo.GetContent(certificateKey);
                            foundRecipient = true;
                        }
                    }
                } catch (Exception f) {
                    throw new PdfException(PdfException.PdfDecryption, f);
                }
            }
            if (!foundRecipient || envelopedData == null)
            {
                throw new PdfException(PdfException.BadCertificateAndKey);
            }
            return(envelopedData);
        }
Example #12
0
        public void TestKeyTransOdes()
        {
            byte[] data = Encoding.ASCII.GetBytes("WallaWallaBouncyCastle");

            CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();

            edGen.AddKeyTransRecipient(ReciCert);

            CmsEnvelopedData ed = edGen.Generate(
                new CmsProcessableByteArray(data),
                OiwObjectIdentifiers.DesCbc.Id);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            Assert.AreEqual(ed.EncryptionAlgOid, OiwObjectIdentifiers.DesCbc.Id);

            ICollection c = recipients.GetRecipients();

            Assert.AreEqual(1, c.Count);

            foreach (RecipientInformation recipient in c)
            {
                byte[] recData = recipient.GetContent(ReciKP.Private);

                Assert.IsTrue(Arrays.AreEqual(data, recData));
            }
        }
Example #13
0
        public void TestKeyTrans128RC4()
        {
            byte[] data = Encoding.ASCII.GetBytes("WallaWallaBouncyCastle");

            CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();

            edGen.AddKeyTransRecipient(ReciCert);

            CmsEnvelopedData ed = edGen.Generate(
                new CmsProcessableByteArray(data),
                "1.2.840.113549.3.4", 128);                  // RC4 OID

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            Assert.AreEqual(ed.EncryptionAlgOid, "1.2.840.113549.3.4");

            ICollection c = recipients.GetRecipients();

            Assert.AreEqual(1, c.Count);

            foreach (RecipientInformation recipient in c)
            {
                byte[] recData = recipient.GetContent(ReciKP.Private);

                Assert.IsTrue(Arrays.AreEqual(data, recData));
            }
        }
Example #14
0
        public string Decrypt(string cipherText)
        {
            byte[] cipherBytes   = Convert.FromBase64String(cipherText);
            var    envelopedData = new CmsEnvelopedData(cipherBytes);
            RecipientInformationStore recipientsStore = envelopedData.GetRecipientInfos();
            ICollection recipientsCollection          = recipientsStore.GetRecipients();
            IList       recipients = recipientsCollection as IList;

            byte[] plainBytes = new byte[] { };
            int    index      = 0;

            foreach (KeyTransRecipientInformation recipientInfo in recipients)
            {
                // todo: better approach than catching n exceptions.
                RecipientInformation recipient = recipientsStore.GetFirstRecipient(recipientInfo.RecipientID);
                try
                {
                    plainBytes = recipient.GetContent(this.privateKey);
                    break;
                }
                catch (CmsException e) when(index != recipientsStore.Count - 1)
                {
                }
                index++;
            }
            return(Encoding.UTF8.GetString(plainBytes));
        }
        private void VerifyEnvelopedData(CmsEnvelopedData envelopedData, string symAlgorithmOID)
        {
            byte[] privKeyData = GetRfc4134Data("BobPrivRSAEncrypt.pri");
            IAsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privKeyData);

            Assert.IsTrue(privKey.IsPrivate);
            Assert.IsTrue(privKey is RsaKeyParameters);

            RecipientInformationStore recipients = envelopedData.GetRecipientInfos();

            Assert.AreEqual(envelopedData.EncryptionAlgOid, symAlgorithmOID);

            ArrayList c = new ArrayList(recipients.GetRecipients());

            Assert.LessOrEqual(1, c.Count);
            Assert.GreaterOrEqual(2, c.Count);

            VerifyRecipient((RecipientInformation)c[0], privKey);

            if (c.Count == 2)
            {
                RecipientInformation recInfo = (RecipientInformation)c[1];

                Assert.AreEqual(PkcsObjectIdentifiers.IdAlgCmsRC2Wrap.Id, recInfo.KeyEncryptionAlgOid);
            }
        }
Example #16
0
        public void TestOriginatorInfo()
        {
            CmsEnvelopedData env = new CmsEnvelopedData(CmsSampleMessages.originatorMessage);

            RecipientInformationStore recipients = env.GetRecipientInfos();

            Assert.AreEqual(CmsEnvelopedDataGenerator.DesEde3Cbc, env.EncryptionAlgOid);
        }
        /// <inheritdoc />
        public byte[] Decrypt(byte[] data)
        {
            foreach (var pkcsStore in _allSenderCertificates)
            {
                var certAlias = pkcsStore.Aliases.Cast <string>().First(x => pkcsStore.IsKeyEntry(x));
                var certEntry = pkcsStore.GetCertificate(certAlias);
                var cert      = certEntry.Certificate;

                var envelopedData  = new CmsEnvelopedData(data);
                var recepientInfos = envelopedData.GetRecipientInfos();
                var recepientId    = new RecipientID()
                {
                    Issuer       = cert.IssuerDN,
                    SerialNumber = cert.SerialNumber
                };
                var recepient = recepientInfos[recepientId];
                if (recepient == null)
                {
                    continue;
                }

                var privKeyEntry = pkcsStore.GetKey(certAlias);
                var privKey      = privKeyEntry.Key;

                var decryptedData = recepient.GetContent(privKey);
                var sig           = new CmsSignedData(decryptedData);
                var sigInfos      = sig.GetSignerInfos();
                var signerId      = new SignerID()
                {
                    Issuer       = _receiverCertificate.IssuerDN,
                    SerialNumber = _receiverCertificate.SerialNumber
                };
                var signer = sigInfos.GetFirstSigner(signerId);
                if (!signer.Verify(_receiverCertificate))
                {
                    throw new ExtraEncryptionException("Failed to verify the signature.");
                }

                var verifiedData = new MemoryStream();
                sig.SignedContent.Write(verifiedData);

                return(verifiedData.ToArray());
            }

            throw new ExtraEncryptionException("No certificate for decryption found.");
        }
Example #18
0
        public void TestRfc4134Ex5_2()
        {
            byte[] data = Hex.Decode("5468697320697320736f6d652073616d706c6520636f6e74656e742e");

//			KeyFactory kFact = KeyFactory.GetInstance("RSA");
//			Key key = kFact.generatePrivate(new PKCS8EncodedKeySpec(bobPrivRsaEncrypt));
            AsymmetricKeyParameter key = PrivateKeyFactory.CreateKey(bobPrivRsaEncrypt);

            CmsEnvelopedData ed = new CmsEnvelopedData(rfc4134ex5_2);

            RecipientInformationStore recipients = ed.GetRecipientInfos();

            Assert.AreEqual("1.2.840.113549.3.2", ed.EncryptionAlgOid);

            ICollection c = recipients.GetRecipients();
            IEnumerator e = c.GetEnumerator();

            if (e.MoveNext())
            {
                do
                {
                    RecipientInformation recipient = (RecipientInformation)e.Current;

                    if (recipient is KeyTransRecipientInformation)
                    {
                        byte[] recData = recipient.GetContent(key);

                        Assert.IsTrue(Arrays.AreEqual(data, recData));
                    }
                }while (e.MoveNext());
            }
            else
            {
                Assert.Fail("no recipient found");
            }
        }
Example #19
0
		private void VerifyEnvelopedData(CmsEnvelopedData envelopedData, string symAlgorithmOID)
		{
			byte[] privKeyData = GetRfc4134Data("BobPrivRSAEncrypt.pri");
			AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privKeyData);
			Assert.IsTrue(privKey.IsPrivate);
			Assert.IsTrue(privKey is RsaKeyParameters);

			RecipientInformationStore recipients = envelopedData.GetRecipientInfos();

			Assert.AreEqual(envelopedData.EncryptionAlgOid, symAlgorithmOID);

			ArrayList c = new ArrayList(recipients.GetRecipients());
			Assert.LessOrEqual(1, c.Count);
			Assert.GreaterOrEqual(2, c.Count);

			VerifyRecipient((RecipientInformation)c[0], privKey);

			if (c.Count == 2)
			{
				RecipientInformation recInfo = (RecipientInformation)c[1];

				Assert.AreEqual(PkcsObjectIdentifiers.IdAlgCmsRC2Wrap.Id, recInfo.KeyEncryptionAlgOid);
			}
		}
        /**
         * Prepares everything to decrypt the document.
         *
         * @param encryption encryption dictionary, can be retrieved via
         * {@link Document#getEncryption()}
         * @param documentIDArray document id which is returned via
         * {@link org.apache.pdfbox.cos.COSDocument#getDocumentID()} (not used by
         * this handler)
         * @param decryptionMaterial Information used to decrypt the document.
         *
         * @throws IOException If there is an error accessing data. If verbose mode
         * is enabled, the exception message will provide more details why the
         * match wasn't successful.
         */
        public override void PrepareForDecryption(PdfEncryption encryption, PdfArray documentIDArray, DecryptionMaterial decryptionMaterial)
        {
            if (!(decryptionMaterial is PublicKeyDecryptionMaterial))
            {
                throw new IOException(
                          "Provided decryption material is not compatible with the document");
            }

            SetDecryptMetadata(encryption.IsEncryptMetaData);
            if (encryption.Length != 0)
            {
                this.keyLength = encryption.Length;
            }

            PublicKeyDecryptionMaterial material = (PublicKeyDecryptionMaterial)decryptionMaterial;

            try
            {
                bool foundRecipient = false;
                //Org.BouncyCastle.X509.Extension.
                X509Certificate      certificate  = material.Certificate;
                X509CertificateEntry materialCert = null;
                if (certificate != null)
                {
                    materialCert = new X509CertificateEntry(certificate);
                }

                // the decrypted content of the enveloped data that match
                // the certificate in the decryption material provided
                byte[] envelopedData = null;

                // the bytes of each recipient in the recipients array
                PdfArray array = (PdfArray)encryption.BaseDataObject.Resolve(PdfName.Recipients);
                if (array == null)
                {
                    PdfCryptFilterDictionary defaultCryptFilterDictionary = encryption.DefaultCryptFilterDictionary;
                    array = (PdfArray)defaultCryptFilterDictionary.BaseDataObject.Resolve(PdfName.Recipients);
                }
                byte[][] recipientFieldsBytes = new byte[array.Count][];
                //TODO encryption.getRecipientsLength() and getRecipientStringAt() should be deprecated

                int           recipientFieldsLength = 0;
                StringBuilder extraInfo             = new StringBuilder();
                for (int i = 0; i < array.Count; i++)
                {
                    PdfString recipientFieldString = (PdfString)array.Resolve(i);
                    byte[]    recipientBytes       = recipientFieldString.GetBuffer();

                    CmsEnvelopedData data   = new CmsEnvelopedData(recipientBytes);
                    var recipCertificatesIt = data.GetRecipientInfos().GetRecipients();
                    int j = 0;
                    foreach (RecipientInformation ri in recipCertificatesIt)
                    {
                        // Impl: if a matching certificate was previously found it is an error,
                        // here we just don't care about it
                        RecipientID rid = ri.RecipientID;
                        if (!foundRecipient && rid.Match(materialCert))
                        {
                            foundRecipient = true;
                            var privateKey = material.PrivateKey;
                            // might need to call setContentProvider() if we use PKI token, see
                            // http://bouncy-castle.1462172.n4.nabble.com/CMSException-exception-unwrapping-key-key-invalid-unknown-key-type-passed-to-RSA-td4658109.html
                            //DotNetUtilities.GetKeyPair(ri.AlgorithmIdentifier)
                            envelopedData = ri.GetContent(privateKey.Key);
                            break;
                        }
                        j++;
                        if (certificate != null)
                        {
                            extraInfo.Append('\n');
                            extraInfo.Append(j);
                            extraInfo.Append(": ");
                            if (ri is KeyTransRecipientInformation)
                            {
                                appendCertInfo(extraInfo, (KeyTransRecipientInformation)ri, certificate, materialCert);
                            }
                        }
                    }
                    recipientFieldsBytes[i] = recipientBytes;
                    recipientFieldsLength  += recipientBytes.Length;
                }
                if (!foundRecipient || envelopedData == null)
                {
                    throw new IOException("The certificate matches none of " + array.Count
                                          + " recipient entries" + extraInfo.ToString());
                }
                if (envelopedData.Length != 24)
                {
                    throw new IOException("The enveloped data does not contain 24 bytes");
                }
                // now envelopedData contains:
                // - the 20 bytes seed
                // - the 4 bytes of permission for the current user

                byte[] accessBytes = new byte[4];
                Array.Copy(envelopedData, 20, accessBytes, 0, 4);

                AccessPermission currentAccessPermission = new AccessPermission(accessBytes);
                currentAccessPermission.IsReadOnly = true;
                CurrentAccessPermission            = currentAccessPermission;

                // what we will put in the SHA1 = the seed + each byte contained in the recipients array
                byte[] sha1Input = new byte[recipientFieldsLength + 20];

                // put the seed in the sha1 input
                Array.Copy(envelopedData, 0, sha1Input, 0, 20);

                // put each bytes of the recipients array in the sha1 input
                int sha1InputOffset = 20;
                foreach (byte[] recipientFieldsByte in recipientFieldsBytes)
                {
                    Array.Copy(recipientFieldsByte, 0, sha1Input, sha1InputOffset, recipientFieldsByte.Length);
                    sha1InputOffset += recipientFieldsByte.Length;
                }

                byte[] mdResult;
                if (encryption.Version == 4 || encryption.Version == 5)
                {
                    mdResult = SHA256.Create().Digest(sha1Input);

                    // detect whether AES encryption is used. This assumes that the encryption algo is
                    // stored in the PDCryptFilterDictionary
                    // However, crypt filters are used only when V is 4 or 5.
                    PdfCryptFilterDictionary defaultCryptFilterDictionary = encryption.DefaultCryptFilterDictionary;
                    if (defaultCryptFilterDictionary != null)
                    {
                        PdfName cryptFilterMethod = defaultCryptFilterDictionary.CryptFilterMethod;
                        IsAES = PdfName.AESV2.Equals(cryptFilterMethod) || PdfName.AESV3.Equals(cryptFilterMethod);
                    }
                }
                else
                {
                    mdResult = SHA1.Create().Digest(sha1Input);
                }

                // we have the encryption key ...
                encryptionKey = new byte[this.keyLength / 8];
                Array.Copy(mdResult, 0, encryptionKey, 0, this.keyLength / 8);
            }
            catch (Exception e)
            {
                throw new IOException("", e);
            }
        }
Example #21
0
        public MimeEntity DecryptEntity(byte[] encryptedBytes, X509Certificate2 decryptingCertificate)
        {
            try
            {
                if (decryptingCertificate == null)
                {
                    throw new EncryptionException(EncryptionError.NoCertificates);
                }

                // TODO: introduce buffering if you are using large files
                // CMSEnvelopeData is a PKCS# structure  rfc4134
                var envelopedData = new CmsEnvelopedData(encryptedBytes);
                var envData       = EnvelopedData.GetInstance(envelopedData.ContentInfo.Content);

                using (var session = GetSession())
                {
                    if (session == null)
                    {
                        return(null);
                    }

                    foreach (Asn1Sequence asn1Set in envData.RecipientInfos)
                    {
                        var recip = RecipientInfo.GetInstance(asn1Set);
                        var keyTransRecipientInfo = KeyTransRecipientInfo.GetInstance(recip.Info);

                        var sessionKey = Pkcs11Util.Decrypt(session, keyTransRecipientInfo, decryptingCertificate);

#if DEBUG
                        Console.WriteLine(Asn1Dump.DumpAsString(envData));
#endif
                        if (sessionKey == null)
                        {
                            continue;
                        }

                        var recipientId           = new RecipientID();
                        var issuerAndSerialNumber = (IssuerAndSerialNumber)keyTransRecipientInfo.RecipientIdentifier.ID;
                        recipientId.Issuer       = issuerAndSerialNumber.Name;
                        recipientId.SerialNumber = issuerAndSerialNumber.SerialNumber.Value;
                        var recipientInformation = envelopedData.GetRecipientInfos().GetRecipients(recipientId);
                        var recipients           = new ArrayList(recipientInformation);

                        //
                        // read the encrypted content info
                        //
                        var encInfo      = envData.EncryptedContentInfo;
                        var encAlg       = encInfo.ContentEncryptionAlgorithm;
                        var readable     = new CmsProcessableByteArray(encInfo.EncryptedContent.GetOctets());
                        var keyParameter = ParameterUtilities.CreateKeyParameter(encAlg.Algorithm.Id, sessionKey);

                        // Todo: does this work with multi recipient?
                        foreach (RecipientInformation recipient in recipients)
                        {
                            var cmsReadable    = GetReadable(keyParameter, encAlg, readable);
                            var cmsTypedStream = new CmsTypedStream(cmsReadable.GetInputStream());
                            var contentBytes   = StreamToByteArray(cmsTypedStream.ContentStream);
                            var mimeEntity     = MimeSerializer.Default.Deserialize <MimeEntity>(contentBytes);
                            return(mimeEntity);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Error.NotifyEvent(this, ex);
            }

            return(null);
        }