예제 #1
0
        public Stream Complete(Stream sealedData, out TimemarkKey timemarkKey)
        {
#if NETFRAMEWORK
            trace.TraceEvent(TraceEventType.Information, 0, "Completing the provided sealed message with revocation and time info according to the level {0}", this.level);
#else
            logger.LogInformation("Completing the provided sealed message with revocation and time info according to the level {0}", this.level);
#endif

            ITempStreamFactory factory   = NewFactory(sealedData);
            Stream             completed = factory.CreateNew();
            Complete(this.level, completed, sealedData, null, null, out timemarkKey);
            completed.Position = 0;

            return(completed);
        }
예제 #2
0
        private Stream Seal(ITempStreamFactory factory, Stream unsealedStream, SecretKey key, X509Certificate2[] certs)
        {
            trace.TraceEvent(TraceEventType.Information, 0, "Sealing message of {0} bytes for {1} known recipients and {2} unknown recipients to level {3}",
                unsealedStream.Length, certs.Length, key == null ? 0 : 1, this.level);

            //Create inner signed stream
            Stream signed = factory.CreateNew();
            using (signed)
            {
                //Inner sign
                Stream intermedate = factory.CreateNew();
                using (intermedate)
                {
                    if (signature == null)
                    {
                        Sign(signed, unsealedStream, authentication);

                        signed.Position = 0;

                        signed.CopyTo(intermedate);
                    }
                    else
                    {
                        Sign(signed, unsealedStream, signature);

                        signed.Position = 0;

                        //Add the certificate and revocation info only (no time-stamp)
                        TimemarkKey timemarkKey;
                        Complete(this.level & ~Level.T_Level, intermedate, signed, signature, out timemarkKey);
                    }

                    intermedate.Position = 0;

                    //Create  encrypted stream
                    Stream signedEncrypted = factory.CreateNew();
                    using (signedEncrypted)
                    {
                        //Encrypt
                        Encrypt(signedEncrypted, intermedate, certs, key);

                        //Outer sign with retry for eID
                        int tries = 0;
                        bool success = false;
                        Stream sealedStream = null;
                        while (!success)
                        {
                            signedEncrypted.Position = 0;

                            try
                            {
                                //This is the output, so we need to make it a temp stream (temp file or memory stream)
                                sealedStream = factory.CreateNew();
                                Sign(sealedStream, signedEncrypted, authentication);
                                success = true;
                            }
                            catch (CryptographicException ce)
                            {
                                //Keep track
                                trace.TraceEvent(TraceEventType.Warning, 0, "Failed to put outer signature (try {0}): {1}", tries, ce);
                                if (tries++ < 4)
                                {
                                    sealedStream.Close();
                                    sealedStream = null;
                                    Thread.Sleep((int)Math.Pow(10, tries)); //wait longer and longer
                                }
                                else
                                {
                                    sealedStream.Close();
                                    throw ce;
                                }
                            }
                        }

                        try
                        {
                            sealedStream.Position = 0; //reset the stream

                            //Complete the outer signature with revocation info & time-stamp if needed
                            TimemarkKey timemarkKey;
                            Stream completedStream = factory.CreateNew();
                            Complete(this.level, completedStream, sealedStream, authentication, out timemarkKey);

                            completedStream.Position = 0; //reset the stream

                            return completedStream;
                        }
                        finally
                        {
                            sealedStream.Close();
                        }
                    }
                }
            }
        }
예제 #3
0
        private Stream Seal(ITempStreamFactory factory, Stream unsealedStream, SecretKey skey, X509Certificate2[] certs, WebKey[] webKeys)
        {
#if NETFRAMEWORK
            trace.TraceEvent(TraceEventType.Information, 0, "Sealing message of {0} bytes for {1}/{2} known recipients and {3} unknown recipients to level {3}",
                             unsealedStream.Length, certs?.Length, webKeys?.Length, skey == null ? 0 : 1, this.level);
#else
            logger.LogInformation("Sealing message of {0} bytes for {1}/{2} known recipients and {3} unknown recipients to level {3}",
                                  unsealedStream.Length, certs?.Length, webKeys?.Length, skey == null ? 0 : 1, this.level);
#endif

            using (
                Stream innerDetached = new MemoryStream(),
                innerEmbedded = factory.CreateNew(),
                encrypted = factory.CreateNew(),
                outerDetached = new MemoryStream()
                )
            {
                TimemarkKey timemarkKey;

                //Inner sign
                if (signature != null)
                {
                    SignDetached(innerDetached, unsealedStream, signature);
                }
                else if (ownWebKey != null)
                {
                    SignDetached(innerDetached, unsealedStream, ownWebKey.BCKeyPair, ownWebKey.Id);
                }
                else
                {
                    throw new InvalidOperationException("Tripple wrapper must have either cert of keypair for signing");
                }

                //prepare to merge the detached inner signature with its content
                innerDetached.Position  = 0;
                unsealedStream.Position = 0;

                //embed the content in the inner signature and add any required info if it uses a different cert.
                Complete(signature == authentication ? (Level?)null : this.level & ~Level.T_Level, innerEmbedded, innerDetached, unsealedStream, signature, out timemarkKey);

                //prepare to encrypt
                innerEmbedded.Position = 0;

                //Encrypt
                Encrypt(encrypted, innerEmbedded, certs, skey, webKeys);

                //Loop, since eID doesn't like to be use in very short succession
                int  retry   = 0;
                bool success = false;
                while (!success)
                {
                    //prepare to create the outer signature
                    encrypted.Position = 0;
                    outerDetached.SetLength(0);

                    try
                    {
                        //Create the outer signature
                        if (signature != null)
                        {
                            SignDetached(outerDetached, encrypted, authentication);
                        }
                        else
                        {
                            SignDetached(outerDetached, encrypted, ownWebKey.BCKeyPair, ownWebKey.Id);
                        }
                        success = true;
                    }
                    catch (CryptographicException ce)
                    {
                        if (retry++ < 4)
                        {
#if NETFRAMEWORK
                            trace.TraceEvent(TraceEventType.Warning, 0, "Failed to put outer signature, staring loop: {0}", ce);
#else
                            logger.LogWarning("Failed to put outer signature, staring loop: {0}", ce);
#endif
                            System.Threading.Thread.Sleep((int)Math.Pow(10, retry));
                        }
                        else
                        {
                            throw ce;
                        }
                    }
                }

                //prepare to merge the detached inner signature with its content
                encrypted.Position     = 0;
                outerDetached.Position = 0;

                //embed the content in the out signature and add any required info
                Stream result = factory.CreateNew();
                Complete(this.level, result, outerDetached, encrypted, authentication, out timemarkKey);

                //prepare to return the triple wrapped message
                result.Position = 0;

                //return the triple wrapped message
                return(result);
            }
        }