SecurityHandlerRev6.cs
//
// This code is part of Document Solutions for PDF demos.
// Copyright (c) MESCIUS inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Pdf.Security;

namespace DsPdfWeb.Demos
{
    // This sample demonstrates how to create an encrypted PDF
    // using the Standard Security Handler Revision 6.
    // 
    // Standard Security Handler Revision 6 was added in PDF 2.0.
    // It uses AES 256 encryption, same as the Standard Security Handler Revision 5
    // described in "Adobe Supplement to the ISO 32000 BaseVersion: 1.7 ExtensionLevel: 3",
    // but a new more complex algorithm is used to generate an encryption key.
    //
    // See SecurityHandlers for examples of using other security handlers.
    public class SecurityHandlerRev6
    {
        public int CreatePDF(Stream stream)
        {
            // Sample passwords:
            const string ownerPassword = "I'm the owner";
            const string userPassword = "I'm a user";

            // Step 1: Generate a document with some security attributes:
            var doc0 = new GcPdfDocument();
            var rc0 = Common.Util.AddNote(
                "Demonstrating the use of the Standard Security Handler Revision 6.",
                doc0.NewPage());

            // Create a Rev6 security handler and set security properties:
            var ssh6 = new StandardSecurityHandlerRev6()
            {
                OwnerPassword = ownerPassword,
                UserPassword = userPassword,
                CopyContent = false,
                PrintingPermissions = PrintingPermissions.Disabled,
                EncryptStrings = true,
            };

            // Assign the handler we created to the document so that it is used when saving the PDF:
            doc0.Security.EncryptHandler = ssh6;

            // Save the PDF in a temp file. It will be loaded and examined in the next step:
            var fn = Path.GetTempFileName();
            doc0.Save(fn);

            // Step 2: Load the generated PDF and examine its security attributes:
            var doc = new GcPdfDocument();
            using (var fs = File.OpenRead(fn))
            {
                // User password is needed to load the document:
                doc.Load(fs, userPassword);

                // At this point we can examine doc.Security.DecryptHandler if it exists,
                // but there is NO Security.EncryptHandler:
                if (doc.Security.EncryptHandler != null)
                    throw new Exception("This should not happen.");

                var dh = doc.Security.DecryptHandler;
                if (dh is StandardSecurityHandlerRev6 dh_ssh6)
                {
                    // Print out some of the permissions in the loaded PDF that was generated in Step 1:
                    var txt = $"Some of the security attributes found in the PDF " +
                        $"that was generated using StandardSecurityHandlerRev6:\n" +
                        $"- EncryptionAlgorithm: {dh_ssh6.EncryptionAlgorithm}\n" +
                        $"- EncryptionKeyLength: {dh_ssh6.EncryptionKeyLength}\n" +
                        $"- CopyContent: {dh_ssh6.CopyContent}\n" +
                        $"- PrintingPermissions: {dh_ssh6.PrintingPermissions}\n" +
                        $"- EncryptStrings: {dh_ssh6.EncryptStrings}\n" +
                        $"";

                    Common.Util.AddNote(
                        txt,
                        doc.Pages[0],
                        new RectangleF(72, rc0.Bottom + 36, 72 * 6, 72 * 2));

                    // This won't work, sorry:
                    var noway = dh_ssh6.OwnerPassword;
                    if (noway != null)
                        throw new Exception("This should not happen.");
                }

                // Save the new PDF. Please note that because we did not set the Security.EncryptHandler
                // on this PDF, this document (unlike the one that was generated in Step 1) has no security:
                doc.Save(stream);
            }
            // Clean up the temp file:
            File.Delete(fn);
            // Done:
            return doc.Pages.Count;
        }
    }
}