﻿/*******************************************************************************
 * You may amend and distribute as you like, but don't remove this header!
 *
 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
 * See http://www.codeplex.com/EPPlus for details.
 *
 * Copyright (C) 2011  Jan Källman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU Lesser General Public License for more details.
 *
 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
 *
 * All code and executables are provided "as is" with no warranty either express or implied. 
 * The author accepts no liability for any damage or loss of business that this product may cause.
 *
 * Code change notes:
 * 
 * Author							Change						Date
 *******************************************************************************
 * Jan Källman		Added		26-MAR-2012
 *******************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Pkcs;
using OfficeOpenXml.Utils;
using System.IO;

namespace OfficeOpenXml.VBA
{
    /// <summary>
    /// The code signature properties of the project
    /// </summary>
    public class ExcelVbaSignature
    {
        const string schemaRelVbaSignature = "http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature";
        Packaging.ZipPackagePart _vbaPart = null;
        internal ExcelVbaSignature(Packaging.ZipPackagePart vbaPart)
        {
            _vbaPart = vbaPart;
            GetSignature();
        }
        private void GetSignature()
        {
            if (_vbaPart == null) return;
            var rel = _vbaPart.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault();
            if (rel != null)
            {
                Uri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);
                Part = _vbaPart.Package.GetPart(Uri);

                var stream = Part.GetStream();
                BinaryReader br = new BinaryReader(stream);
                uint cbSignature = br.ReadUInt32();        
                uint signatureOffset = br.ReadUInt32();     //44 ??
                uint cbSigningCertStore = br.ReadUInt32();  
                uint certStoreOffset = br.ReadUInt32();     
                uint cbProjectName = br.ReadUInt32();       
                uint projectNameOffset = br.ReadUInt32();   
                uint fTimestamp = br.ReadUInt32();
                uint cbTimestampUrl = br.ReadUInt32();
                uint timestampUrlOffset = br.ReadUInt32();  
                byte[] signature = br.ReadBytes((int)cbSignature);
                uint version = br.ReadUInt32();
                uint fileType = br.ReadUInt32();

                uint id = br.ReadUInt32();
                while (id != 0)
                {
                    uint encodingType = br.ReadUInt32();
                    uint length = br.ReadUInt32();
                    if (length > 0)
                    {
                        byte[] value = br.ReadBytes((int)length);
                        switch (id)
                        {
                            //Add property values here...
                            case 0x20:
                                Certificate = new X509Certificate2(value);
                                break;
                            default:
                                break;
                        }
                    }
                    id = br.ReadUInt32();
                }
                uint endel1 = br.ReadUInt32();  //0
                uint endel2 = br.ReadUInt32();  //0
                ushort rgchProjectNameBuffer = br.ReadUInt16();
                ushort rgchTimestampBuffer = br.ReadUInt16();
                Verifier = new SignedCms();
                Verifier.Decode(signature);
            }
            else
            {
                Certificate = null;
                Verifier = null;
            }
        }
        //Create Oid from a bytearray
        //private string ReadHash(byte[] content)
        //{
        //    StringBuilder builder = new StringBuilder();
        //    int offset = 0x6;
        //    if (0 < (content.Length))
        //    {
        //        byte num = content[offset];
        //        byte num2 = (byte)(num / 40);
        //        builder.Append(num2.ToString(null, null));
        //        builder.Append(".");
        //        num2 = (byte)(num % 40);
        //        builder.Append(num2.ToString(null, null));
        //        ulong num3 = 0L;
        //        for (int i = offset + 1; i < content.Length; i++)
        //        {
        //            num2 = content[i];
        //            num3 = (ulong)(ulong)(num3 << 7) + ((byte)(num2 & 0x7f));
        //            if ((num2 & 0x80) == 0)
        //            {
        //                builder.Append(".");
        //                builder.Append(num3.ToString(null, null));
        //                num3 = 0L;
        //            }
        //            //1.2.840.113549.2.5
        //        }
        //    }


        //    string oId = builder.ToString();

        //    return oId;
        //}
        internal void Save(ExcelVbaProject proj)
        {
            if (Certificate == null)
            {
                return;
            }
            
            if (Certificate.HasPrivateKey==false)    //No signature. Remove any Signature part
            {
                var storeCert = GetCertFromStore(StoreLocation.CurrentUser);
                if (storeCert == null)
                {
                    storeCert = GetCertFromStore(StoreLocation.LocalMachine);
                }
                if (storeCert != null && storeCert.HasPrivateKey == true)
                {
                    Certificate = storeCert;
                }
                else
                {
                    foreach (var r in Part.GetRelationships())
                    {
                        Part.DeleteRelationship(r.Id);
                    }
                    Part.Package.DeletePart(Part.Uri);
                    return;
                }
            }
            var ms = new MemoryStream();
            var bw = new BinaryWriter(ms);

            byte[] certStore = GetCertStore();

            byte[] cert = SignProject(proj);
            bw.Write((uint)cert.Length);
            bw.Write((uint)44);                  //?? 36 ref inside cert ??
            bw.Write((uint)certStore.Length);    //cbSigningCertStore
            bw.Write((uint)(cert.Length + 44));  //certStoreOffset
            bw.Write((uint)0);                   //cbProjectName
            bw.Write((uint)(cert.Length + certStore.Length + 44));    //projectNameOffset
            bw.Write((uint)0);    //fTimestamp
            bw.Write((uint)0);    //cbTimestampUrl
            bw.Write((uint)(cert.Length + certStore.Length + 44 + 2));    //timestampUrlOffset
            bw.Write(cert);
            bw.Write(certStore);
            bw.Write((ushort)0);//rgchProjectNameBuffer
            bw.Write((ushort)0);//rgchTimestampBuffer
            bw.Write((ushort)0);
            bw.Flush();

            var rel = proj.Part.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault();
            if (Part == null)
            {

                if (rel != null)
                {
                    Uri = rel.TargetUri;
                    Part = proj._pck.GetPart(rel.TargetUri);
                }
                else
                {
                    Uri = new Uri("/xl/vbaProjectSignature.bin", UriKind.Relative);
                    Part = proj._pck.CreatePart(Uri, ExcelPackage.schemaVBASignature);
                }
            }
            if (rel == null)
            {
                proj.Part.CreateRelationship(UriHelper.ResolvePartUri(proj.Uri, Uri), Packaging.TargetMode.Internal, schemaRelVbaSignature);                
            }
            var b = ms.ToArray();
            Part.GetStream(FileMode.Create).Write(b, 0, b.Length);            
        }

        private X509Certificate2 GetCertFromStore(StoreLocation loc)
        {
            try
            {
                X509Store store = new X509Store(loc);
                store.Open(OpenFlags.ReadOnly);
                try
                {
                    var storeCert = store.Certificates.Find(
                                    X509FindType.FindByThumbprint,
                                    Certificate.Thumbprint,
                                    true
                                    ).OfType<X509Certificate2>().FirstOrDefault();
                    return storeCert;
                }
                finally
                {
                    store.Close();
                }
            }
            catch
            {
                return null;
            }
        }

        private byte[] GetCertStore()
        {
            var ms = new MemoryStream();
            var bw = new BinaryWriter(ms);

            bw.Write((uint)0); //Version
            bw.Write((uint)0x54524543); //fileType

            //SerializedCertificateEntry
            var certData = Certificate.RawData;
            bw.Write((uint)0x20);
            bw.Write((uint)1);
            bw.Write((uint)certData.Length);
            bw.Write(certData);

            //EndElementMarkerEntry
            bw.Write((uint)0);
            bw.Write((ulong)0);

            bw.Flush();
            return ms.ToArray();
        }

        private void WriteProp(BinaryWriter bw, int id, byte[] data)
        {
            bw.Write((uint)id);
            bw.Write((uint)1);
            bw.Write((uint)data.Length);
            bw.Write(data);
        }
        internal byte[] SignProject(ExcelVbaProject proj)
        {
            if (!Certificate.HasPrivateKey)
            {
                //throw (new InvalidOperationException("The certificate doesn't have a private key"));
                Certificate = null;
                return null;
            }
            var hash = GetContentHash(proj);

            BinaryWriter bw = new BinaryWriter(new MemoryStream());
            bw.Write((byte)0x30); //Constructed Type 
            bw.Write((byte)0x32); //Total length
            bw.Write((byte)0x30); //Constructed Type 
            bw.Write((byte)0x0E); //Length SpcIndirectDataContent
            bw.Write((byte)0x06); //Oid Tag Indentifier 
            bw.Write((byte)0x0A); //Lenght OId
            bw.Write(new byte[] { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x1D }); //Encoded Oid 1.3.6.1.4.1.311.2.1.29
            bw.Write((byte)0x04);   //Octet String Tag Identifier
            bw.Write((byte)0x00);   //Zero length

            bw.Write((byte)0x30); //Constructed Type (DigestInfo)
            bw.Write((byte)0x20); //Length DigestInfo
            bw.Write((byte)0x30); //Constructed Type (Algorithm)
            bw.Write((byte)0x0C); //length AlgorithmIdentifier
            bw.Write((byte)0x06); //Oid Tag Indentifier 
            bw.Write((byte)0x08); //Lenght OId
            bw.Write(new byte[] { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 }); //Encoded Oid for 1.2.840.113549.2.5 (AlgorithmIdentifier MD5)
            bw.Write((byte)0x05);   //Null type identifier
            bw.Write((byte)0x00);   //Null length
            bw.Write((byte)0x04);   //Octet String Identifier
            bw.Write((byte)hash.Length);   //Hash length
            bw.Write(hash);                //Content hash

            ContentInfo contentInfo = new ContentInfo(((MemoryStream)bw.BaseStream).ToArray());
            contentInfo.ContentType.Value = "1.3.6.1.4.1.311.2.1.4";
            Verifier = new SignedCms(contentInfo);
            var signer = new CmsSigner(Certificate);
            Verifier.ComputeSignature(signer, false);
            return Verifier.Encode();
        }

        private byte[] GetContentHash(ExcelVbaProject proj)
        {
            //MS-OVBA 2.4.2
            var enc = System.Text.Encoding.GetEncoding(proj.CodePage);
            BinaryWriter bw = new BinaryWriter(new MemoryStream());
            bw.Write(enc.GetBytes(proj.Name));
            bw.Write(enc.GetBytes(proj.Constants));
            foreach (var reference in proj.References)
            {
                if (reference.ReferenceRecordID == 0x0D)
                {
                    bw.Write((byte)0x7B);
                }
                if (reference.ReferenceRecordID == 0x0E)
                {
                    //var r = (ExcelVbaReferenceProject)reference;
                    //BinaryWriter bwTemp = new BinaryWriter(new MemoryStream());
                    //bwTemp.Write((uint)r.Libid.Length);
                    //bwTemp.Write(enc.GetBytes(r.Libid));              
                    //bwTemp.Write((uint)r.LibIdRelative.Length);
                    //bwTemp.Write(enc.GetBytes(r.LibIdRelative));
                    //bwTemp.Write(r.MajorVersion);
                    //bwTemp.Write(r.MinorVersion);
                    foreach (byte b in BitConverter.GetBytes((uint)reference.Libid.Length))  //Length will never be an UInt with 4 bytes that aren't 0 (> 0x00FFFFFF), so no need for the rest of the properties.
                    {
                        if (b != 0)
                        {
                            bw.Write(b);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            foreach (var module in proj.Modules)
            {
                var lines = module.Code.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var line in lines)
                {
                    if (!line.StartsWith("attribute", true, null))
                    {
                        bw.Write(enc.GetBytes(line));
                    }
                }
            }
            var buffer = (bw.BaseStream as MemoryStream).ToArray();
            var hp = System.Security.Cryptography.MD5CryptoServiceProvider.Create();
            return hp.ComputeHash(buffer);
        }
        /// <summary>
        /// The certificate to sign the VBA project.
        /// <remarks>
        /// This certificate must have a private key.
        /// There is no validation that the certificate is valid for codesigning, so make sure it's valid to sign Excel files (Excel 2010 is more strict that prior versions).
        /// </remarks>
        /// </summary>
        public X509Certificate2 Certificate { get; set; }
        /// <summary>
        /// The verifier
        /// </summary>
        public SignedCms Verifier { get; internal set; }
#if !MONO
        internal CompoundDocument Signature { get; set; }
#endif
        internal Packaging.ZipPackagePart Part { get; set; }
        internal Uri Uri { get; private set; }
    }
}
