Пример #1
0
            public override void Close()
            {
                macStream.Close();
                eiGen.Close();

                // [TODO] auth attributes go here
                byte[] macOctets = MacUtilities.DoFinal(macStream.WriteMac());
                authGen.AddObject(new DerOctetString(macOctets));
                // [TODO] unauth attributes go here

                authGen.Close();
                cGen.Close();
            }
Пример #2
0
        /// <inheritdoc />
        protected override void FinishItem(PayloadItem item, CipherStream encryptor, MacStream authenticator)
        {
            if (Writing)
            {
                if (item.ExternalLength > 0 && encryptor.BytesIn != item.ExternalLength)
                {
                    throw new InvalidDataException("Length written is not equal to predefined item external length.");
                }
            }
            else
            {
                if (encryptor.BytesIn != item.InternalLength)
                {
                    throw new InvalidDataException("Length read is not equal to item internal length.");
                }
                if (encryptor.BytesOut != item.ExternalLength)
                {
                    throw new InvalidDataException("Demultiplexed and decrypted length is not equal to specified item external length.");
                }
                encryptor.Close();
            }

            if (Writing)
            {
                // Commit the determined internal length to item in payload manifest
                item.InternalLength = encryptor.BytesOut;
                EmitTrailer(authenticator);
            }
            else
            {
                ConsumeTrailer(authenticator);
            }

            // Final stages of Encrypt-then-MAC authentication scheme
            PayloadItem itemDto = item.CreateAuthenticatibleClone();

            byte[] itemDtoAuthBytes = itemDto.SerialiseDto();

            Debug.Print(DebugUtility.CreateReportString("FabricPayloadMux", "FinishItem", "Item DTO length",
                                                        itemDtoAuthBytes.Length));

            if (Writing)
            {
                authenticator.Update(itemDtoAuthBytes, 0, itemDtoAuthBytes.Length);
                authenticator.Close();
                // Commit the MAC to item in payload manifest
                item.AuthenticationVerifiedOutput = authenticator.Mac.DeepCopy();
            }
            else
            {
                authenticator.Update(itemDtoAuthBytes, 0, itemDtoAuthBytes.Length);
                authenticator.Close();
                // Verify the authenticity of the item ciphertext and configuration
                if (authenticator.Mac.SequenceEqual_ConstantTime(item.AuthenticationVerifiedOutput) == false)
                {
                    // Verification failed!
                    throw new CiphertextAuthenticationException("Payload item not authenticated.");
                }
            }


            // Release the item's resources (implicitly - no references remain)
            _activeItemResources.Remove(item.Identifier);

            // Mark the item as completed in the register
            ItemCompletionRegister[Index] = true;
            ItemsCompleted++;
            // Close the source/destination
            item.StreamBinding.Close();

            Debug.Print(DebugUtility.CreateReportString("FabricPayloadMux", "FinishItem", "[*** END OF ITEM",
                                                        Index + " ***]"));
        }
        /**
         * generate an enveloped object that contains an CMS Enveloped Data
         * object using the given provider and the passed in key generator.
         */
        private CmsAuthenticatedData Generate(
            CmsProcessable content,
            string macOid,
            CipherKeyGenerator keyGen)
        {
            AlgorithmIdentifier macAlgId;
            KeyParameter        encKey;
            Asn1OctetString     encContent;
            Asn1OctetString     macResult;

            try
            {
                // FIXME Will this work for macs?
                byte[] encKeyBytes = keyGen.GenerateKey();
                encKey = ParameterUtilities.CreateKeyParameter(macOid, encKeyBytes);

                Asn1Encodable asn1Params = GenerateAsn1Parameters(macOid, encKeyBytes);

                ICipherParameters cipherParameters;
                macAlgId = GetAlgorithmIdentifier(
                    macOid, encKey, asn1Params, out cipherParameters);

                IMac mac = MacUtilities.GetMac(macOid);
                // TODO Confirm no ParametersWithRandom needed
                // FIXME Only passing key at the moment
//	            mac.Init(cipherParameters);
                mac.Init(encKey);

                MemoryStream bOut = new MemoryStream();
                MacStream    mOut = new MacStream(bOut, null, mac);

                content.Write(mOut);

                mOut.Close();
                bOut.Close();

                encContent = new BerOctetString(bOut.ToArray());

                byte[] macOctets = MacUtilities.DoFinal(mOut.WriteMac());
                macResult = new DerOctetString(macOctets);
            }
            catch (SecurityUtilityException e)
            {
                throw new CmsException("couldn't create cipher.", e);
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException("key invalid in message.", e);
            }
            catch (IOException e)
            {
                throw new CmsException("exception decoding algorithm parameters.", e);
            }


            Asn1EncodableVector recipientInfos = new Asn1EncodableVector();

            foreach (RecipientInfoGenerator rig in recipientInfoGenerators)
            {
                try
                {
                    recipientInfos.Add(rig.Generate(encKey, rand));
                }
                catch (InvalidKeyException e)
                {
                    throw new CmsException("key inappropriate for algorithm.", e);
                }
                catch (GeneralSecurityException e)
                {
                    throw new CmsException("error making encrypted content.", e);
                }
            }

            ContentInfo eci = new ContentInfo(CmsObjectIdentifiers.Data, encContent);

            ContentInfo contentInfo = new ContentInfo(
                CmsObjectIdentifiers.AuthenticatedData,
                new AuthenticatedData(null, new DerSet(recipientInfos), macAlgId, null, eci, null, macResult, null));

            return(new CmsAuthenticatedData(contentInfo));
        }
Пример #4
0
        /// <summary>
        ///     Close the item decorator, check lengths, authenticate the item (emit or verify),
        ///     and if writing, commit the authentication value to the payload item DTO.
        /// </summary>
        /// <param name="item">Payload item to finish.</param>
        /// <param name="encryptor">Item encryptor/cipher.</param>
        /// <param name="authenticator">Item authenticator/MAC.</param>
        protected override void FinishItem(PayloadItem item, CipherStream encryptor, MacStream authenticator)
        {
            try {
                encryptor.Close();
            } catch (Exception e) {
                throw new Exception("Unknown error when finalising/closing cipher.", e);
            }

            try {
                if (Writing)
                {
                    EmitTrailer(authenticator);
                }
                else
                {
                    ConsumeTrailer(authenticator);
                }
            } catch (Exception e) {
                throw new Exception(String.Format("Unknown error when {0} item trailer.", Writing ? "emitting" : "consuming"), e);
            }

            // Length checks & commits
            if (Writing)
            {
                // Check if pre-stated length matches what was actually written
                if (item.ExternalLength > 0 && encryptor.BytesIn != item.ExternalLength)
                {
                    throw new InvalidDataException(
                              "Mismatch between stated item external length and actual input length.");
                }
                // Commit the determined internal length to item in payload manifest
                item.InternalLength = encryptor.BytesOut;
            }
            else
            {
                if (encryptor.BytesIn != item.InternalLength)
                {
                    throw new InvalidOperationException("Probable decorator stack malfunction.");
                }
                if (encryptor.BytesOut != item.ExternalLength)
                {
                    throw new InvalidDataException(
                              "Mismatch between stated item external length and actual output length.");
                }
            }

            // Final stages of Encrypt-then-MAC authentication scheme
            PayloadItem itemDto = item.CreateAuthenticatibleClone();

            byte[] itemDtoAuthBytes = itemDto.SerialiseDto();
#if PRINT_DTO_LENGTH
            Debug.Print(DebugUtility.CreateReportString("SimplePayloadMux", "FinishItem", "Payload item DTO length",
                                                        itemDtoAuthBytes.Length));
#endif
            authenticator.Update(itemDtoAuthBytes, 0, itemDtoAuthBytes.Length);
            authenticator.Close();

            // Authentication
            if (Writing)
            {
                // Commit the MAC to item in payload manifest
                item.AuthenticationVerifiedOutput = authenticator.Mac.DeepCopy();
            }
            else
            {
                // Verify the authenticity of the item ciphertext and configuration
                if (authenticator.Mac.SequenceEqual_ConstantTime(item.AuthenticationVerifiedOutput) == false)
                {
                    // Verification failed!
                    throw new CiphertextAuthenticationException("Payload item not authenticated.");
                }
            }

            // Close the source/destination
            item.StreamBinding.Close();

            // Mark the item as completed in the register
            ItemCompletionRegister[Index] = true;
            ItemsCompleted++;

            Debug.Print(DebugUtility.CreateReportString("SimplePayloadMux", "ExecuteOperation",
                                                        "[*** END OF ITEM", String.Format("{0} ({1}) ***]", Index, item.Identifier)));
        }