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); }
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(); } } } } }
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); } }