﻿/*******************************************************************************
 * 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       		        2013-01-05
 *******************************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;

namespace OfficeOpenXml.Encryption
{
    internal abstract class EncryptionInfo
    {
        internal short MajorVersion;
        internal short MinorVersion;
        internal abstract void Read(byte[] data);

        internal static EncryptionInfo ReadBinary(byte[] data)
        {
            var majorVersion = BitConverter.ToInt16(data, 0);
            var minorVersion = BitConverter.ToInt16(data, 2);
            EncryptionInfo ret;
            if ((minorVersion == 2 || minorVersion == 3) && majorVersion <= 4) // minorVersion==1 is RC4, not supported.
            {
                ret = new EncryptionInfoBinary();
            }
            else if (majorVersion == 4 && minorVersion==4)
            {
                ret = new EncryptionInfoAgile();
            }
            else
            {
                throw (new NotSupportedException("Unsupported encryption format"));
            }
            ret.MajorVersion = majorVersion;
            ret.MinorVersion = minorVersion;
            ret.Read(data);
            return ret;
        }
    }
    internal enum eCipherAlgorithm
    {
        /// <summary>
        /// AES. MUST conform to the AES algorithm.
        /// </summary>
        AES,
        /// <summary>
        /// RC2. MUST conform to [RFC2268].
        /// </summary>
        RC2,
        /// <summary>
        /// RC4. 
        /// </summary>
        RC4,
        /// <summary>
        /// MUST conform to the DES algorithm.
        /// </summary>
        DES,
        /// <summary>
        /// MUST conform to the [DRAFT-DESX] algorithm.
        /// </summary>
        DESX,
        /// <summary>
        /// 3DES. MUST conform to the [RFC1851] algorithm. 
        /// </summary>
        TRIPLE_DES,
        /// 3DES_112 MUST conform to the [RFC1851] algorithm. 
        TRIPLE_DES_112        
    }
    internal enum eChainingMode
    {
        /// <summary>
        /// Cipher block chaining (CBC).
        /// </summary>
        ChainingModeCBC,
        /// <summary>
        /// Cipher feedback chaining (CFB), with 8-bit window.
        /// </summary>
        ChainingModeCFB
    }
    /// <summary>
    /// Hashalgorithm
    /// </summary>
    internal enum eHashAlogorithm
    {
        /// <summary>
        /// Sha 1-MUST conform to [RFC4634]
        /// </summary>
        SHA1,
        /// <summary>
        /// Sha 256-MUST conform to [RFC4634]
        /// </summary>
        SHA256,
        /// <summary>
        /// Sha 384-MUST conform to [RFC4634]
        /// </summary>
        SHA384,
        /// <summary>
        /// Sha 512-MUST conform to [RFC4634]
        /// </summary>
        SHA512,
        /// <summary>
        /// MD5
        /// </summary>
        MD5,
        /// <summary>
        /// MD4
        /// </summary>
        MD4,
        /// <summary>
        /// MD2
        /// </summary>
        MD2,
        /// <summary>
        /// RIPEMD-128 MUST conform to [ISO/IEC 10118]
        /// </summary>
        RIPEMD128,
        /// <summary>
        /// RIPEMD-160 MUST conform to [ISO/IEC 10118]
        /// </summary>
        RIPEMD160,
        /// <summary>
        /// WHIRLPOOL MUST conform to [ISO/IEC 10118]
        /// </summary>
        WHIRLPOOL
    }
    /// <summary>
    /// Handels the agile encryption
    /// </summary>
    internal class EncryptionInfoAgile : EncryptionInfo
    {
        XmlNamespaceManager _nsm;
        public EncryptionInfoAgile()
        {
            var nt = new NameTable();
            _nsm = new XmlNamespaceManager(nt);
            _nsm.AddNamespace("d", "http://schemas.microsoft.com/office/2006/encryption");
            _nsm.AddNamespace("c", "http://schemas.microsoft.com/office/2006/keyEncryptor/certificate");
            _nsm.AddNamespace("p", "http://schemas.microsoft.com/office/2006/keyEncryptor/password");
        }
        internal class EncryptionKeyData : XmlHelper
        {
            public EncryptionKeyData(XmlNamespaceManager nsm, XmlNode topNode) :
                base(nsm, topNode)
            {

            }
            internal byte[] SaltValue
            {
                get
                {
                    var s = GetXmlNodeString("@saltValue");
                    if (!string.IsNullOrEmpty(s))
                    {
                        return Convert.FromBase64String(s);
                    }
                    return null;
                }
                set
                {
                    SetXmlNodeString("@saltValue", Convert.ToBase64String(value));
                }
            }
            internal eHashAlogorithm HashAlgorithm
            {
                get
                {
                    return GetHashAlgorithm(GetXmlNodeString("@hashAlgorithm"));
                }
                set
                {
                    SetXmlNodeString("@hashAlgorithm", GetHashAlgorithmString(value));
                }
            }

            private eHashAlogorithm GetHashAlgorithm(string v)
            {
                switch (v)
                {
                    case "RIPEMD-128":
                        return eHashAlogorithm.RIPEMD128;
                    case "RIPEMD-160":
                        return eHashAlogorithm.RIPEMD160;
                    case "SHA-1":
                        return eHashAlogorithm.SHA1;
                    default:
                        try
                        {
                            return (eHashAlogorithm)Enum.Parse(typeof(eHashAlogorithm),v);
                        }
                        catch
                        {
                            throw (new InvalidDataException("Invalid Hash algorithm"));
                        }
                }
            }

            private string GetHashAlgorithmString(eHashAlogorithm value)
            {
                switch (value)
                {
                    case eHashAlogorithm.RIPEMD128:
                        return "RIPEMD-128";
                    case eHashAlogorithm.RIPEMD160:
                        return "RIPEMD-160";
                    case eHashAlogorithm.SHA1:
                        return "SHA-1";
                    default: 
                        return value.ToString();
                }
            }
            internal eChainingMode ChiptherChaining
            {
                get
                {
                    var v=GetXmlNodeString("@cipherChaining");
                    try
                    {
                        return (eChainingMode)Enum.Parse(typeof(eChainingMode), v);
                    }
                    catch
                    {
                        throw (new InvalidDataException("Invalid chaining mode"));
                    }
                }
                set
                {
                    SetXmlNodeString("@cipherChaining", value.ToString());
                }
            }
            internal eCipherAlgorithm CipherAlgorithm
            {
                get
                {
                    return GetCipherAlgorithm(GetXmlNodeString("@cipherAlgorithm"));
                }
                set
                {
                    SetXmlNodeString("@cipherAlgorithm", GetCipherAlgorithmString(value));
                }
            }

            private eCipherAlgorithm GetCipherAlgorithm(string v)
            {
                switch (v)
                {
                    case "3DES":
                        return eCipherAlgorithm.TRIPLE_DES;
                    case "3DES_112":
                        return eCipherAlgorithm.TRIPLE_DES_112;
                    default:
                        try
                        {
                            return (eCipherAlgorithm)Enum.Parse(typeof(eCipherAlgorithm), v);
                        }
                        catch
                        {
                            throw (new InvalidDataException("Invalid Hash algorithm"));
                        }
                }
            }

            private string GetCipherAlgorithmString(eCipherAlgorithm alg)
            {
                switch (alg)
                {
                    case eCipherAlgorithm.TRIPLE_DES:
                        return "3DES";
                    case eCipherAlgorithm.TRIPLE_DES_112:
                        return "3DES_112";                    
                    default:
                        return alg.ToString();
                }
            }
            internal int HashSize
            {
                get
                {
                    return GetXmlNodeInt("@hashSize");
                }
                set
                {
                    SetXmlNodeString("@hashSize", value.ToString());
                }
            }
            internal int KeyBits
            {
                get
                {
                    return GetXmlNodeInt("@keyBits");
                }
                set
                {
                    SetXmlNodeString("@keyBits", value.ToString());
                }
            }
            internal int BlockSize
            {
                get
                {
                    return GetXmlNodeInt("@blockSize");
                }
                set
                {
                    SetXmlNodeString("@blockSize", value.ToString());
                }
            }
            internal int SaltSize
            {
                get
                {
                    return GetXmlNodeInt("@saltSize");
                }
                set
                {
                    SetXmlNodeString("@saltSize", value.ToString());
                }
            }
        }
        internal class EncryptionDataIntegrity : XmlHelper
        {
            public EncryptionDataIntegrity(XmlNamespaceManager nsm, XmlNode topNode) :
                base(nsm, topNode)
            {

            }
            internal byte[] EncryptedHmacValue
            {
                get
                {
                    var s = GetXmlNodeString("@encryptedHmacValue");
                    if (!string.IsNullOrEmpty(s))
                    {
                        return Convert.FromBase64String(s);
                    }
                    return null;
                }
                set
                {
                    SetXmlNodeString("@encryptedHmacValue", Convert.ToBase64String(value));
                }
            }
            internal byte[] EncryptedHmacKey
            {
                get
                {
                    var s = GetXmlNodeString("@encryptedHmacKey");
                    if (!string.IsNullOrEmpty(s))
                    {
                        return Convert.FromBase64String(s);
                    }
                    return null;
                }
                set
                {
                    SetXmlNodeString("@encryptedHmacKey", Convert.ToBase64String(value));
                }
            }
        }
        internal class EncryptionKeyEncryptor : EncryptionKeyData
        {
            public EncryptionKeyEncryptor(XmlNamespaceManager nsm, XmlNode topNode) :
                base(nsm, topNode)
            {

            }
            internal byte[] EncryptedKeyValue
            {
                get
                {
                    var s = GetXmlNodeString("@encryptedKeyValue");
                    if (!string.IsNullOrEmpty(s))
                    {
                        return Convert.FromBase64String(s);
                    }
                    return null;
                }
                set
                {
                    SetXmlNodeString("@encryptedKeyValue", Convert.ToBase64String(value));
                }
            }
            internal byte[] EncryptedVerifierHash
            {
                get
                {
                    var s = GetXmlNodeString("@encryptedVerifierHashValue");
                    if (!string.IsNullOrEmpty(s))
                    {
                        return Convert.FromBase64String(s);
                    }
                    return null;

                }
                set
                {
                    SetXmlNodeString("@encryptedVerifierHashValue", Convert.ToBase64String(value));
                }
            }
            internal byte[] EncryptedVerifierHashInput
            {
                get
                {
                    var s = GetXmlNodeString("@encryptedVerifierHashInput");
                    if (!string.IsNullOrEmpty(s))
                    {
                        return Convert.FromBase64String(s);
                    }
                    return null;
                }
                set
                {
                    SetXmlNodeString("@encryptedVerifierHashInput", Convert.ToBase64String(value));
                }
            }
            internal byte[] VerifierHashInput { get; set; }
            internal byte[] VerifierHash { get; set; }
            internal byte[] KeyValue { get; set; }
            internal int SpinCount
            {
                get
                {
                    return GetXmlNodeInt("@spinCount");
                }
                set
                {
                    SetXmlNodeString("@spinCount", value.ToString());
                }
            }
        }
        /*
        <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
           <encryption xmlns="http://schemas.microsoft.com/office/2006/encryption" xmlns:p="http://schemas.microsoft.com/office/2006/keyEncryptor/password" xmlns:c="http://schemas.microsoft.com/office/2006/keyEncryptor/certificate">
               <keyData saltSize="16" blockSize="16" keyBits="256" hashSize="64" cipherAlgorithm="AES" cipherChaining="ChainingModeCBC" hashAlgorithm="SHA512" saltValue="pa+hrJ3s1zrY6hmVuSa5JQ==" />
               <dataIntegrity encryptedHmacKey="nd8i4sEKjsMjVN2gLo91oFN2e7bhMpWKDCAUBEpz4GW6NcE3hBXDobLksZvQGwLrPj0SUVzQA8VuDMyjMAfVCA==" encryptedHmacValue="O6oegHpQVz2uO7Om4oZijSi4kzLiiMZGIjfZlq/EFFO6PZbKitenBqe2or1REaxaI7gO/JmtJzZ1ViucqTaw4g==" />
               <keyEncryptors>
                   <keyEncryptor uri="http://schemas.microsoft.com/office/2006/keyEncryptor/password">
                      <p:encryptedKey spinCount="100000" saltSize="16" blockSize="16" keyBits="256" hashSize="64" cipherAlgorithm="AES" cipherChaining="ChainingModeCBC" hashAlgorithm="SHA512" saltValue="u2BNFAuHYn3M/WRja3/uPg==" encryptedVerifierHashInput="M0V+fRolJMRgFyI9w+AVxQ==" encryptedVerifierHashValue="V/6l9pFH7AaXFqEbsnFBfHe7gMOqFeRwaNMjc7D3LNdw6KgZzOOQlt5sE8/oG7GPVBDGfoQMTxjQydVPVy4qng==" encryptedKeyValue="B0/rbSQRiIKG5CQDH6AKYSybdXzxgKAfX1f+S5k7mNE=" />
                   </keyEncryptor></keyEncryptors></encryption>
        */
        
        /***
         * <?xml version="1.0" encoding="UTF-8" standalone="true"?>
            <encryption xmlns:c="http://schemas.microsoft.com/office/2006/keyEncryptor/certificate" xmlns:p="http://schemas.microsoft.com/office/2006/keyEncryptor/password" xmlns="http://schemas.microsoft.com/office/2006/encryption">
         *      <keyData saltValue="XmTB/XBGJSbwd/GTKzQv5A==" hashAlgorithm="SHA512" cipherChaining="ChainingModeCBC" cipherAlgorithm="AES" hashSize="64" keyBits="256" blockSize="16" saltSize="16"/>
         *      <dataIntegrity encryptedHmacValue="WWw3Bb2dbcNPMnl9f1o7rO0u7sclWGKTXqBA6rRzKsP2KzWS5T0LxY9qFoC6QE67t/t+FNNtMDdMtE3D1xvT8w==" encryptedHmacKey="p/dVdlJY5Kj0k3jI1HRjqtk4s0Y4HmDAsc8nqZgfxNS7DopAsS3LU/2p3CYoIRObHsnHTAtbueH08DFCYGZURg=="/>
         *          <keyEncryptors>
         *              <keyEncryptor uri="http://schemas.microsoft.com/office/2006/keyEncryptor/password">
         *                  <p:encryptedKey saltValue="EeBtY0QftyOkLztCl7NF0g==" hashAlgorithm="SHA512" cipherChaining="ChainingModeCBC" cipherAlgorithm="AES" hashSize="64" keyBits="256" blockSize="16" saltSize="16" encryptedKeyValue="Z7AO8vHnnPZEb1VqyZLJ6JFc3Mq3E322XPxWXS21fbU=" encryptedVerifierHashValue="G7BxbKnZanldvtsbu51mP9J3f9Wr5vCfCpvWSh5eIJff7Sr3J2DzH1/9aKj9uIpqFQIsLohpRk+oBYDcX7hRgw==" encryptedVerifierHashInput="851eszl5y5rdU1RnTjEWHw==" spinCount="100000"/>
         *              </keyEncryptor>
         *      </keyEncryptors>
         *      </encryption
         * ***/
        internal EncryptionDataIntegrity DataIntegrity { get; set; }
        internal EncryptionKeyData KeyData { get; set; }
        internal List<EncryptionKeyEncryptor> KeyEncryptors
        {
            get;
            private set;
        }

        internal XmlDocument Xml {get;set;}
        internal override void Read(byte[] data)
        {
            var byXml = new byte[data.Length - 8];
            Array.Copy(data, 8, byXml, 0, data.Length - 8);
            var xml = Encoding.UTF8.GetString(byXml);
            ReadFromXml(xml);
        }
        internal void ReadFromXml(string xml)
        {
            Xml = new XmlDocument();
            XmlHelper.LoadXmlSafe(Xml, xml, Encoding.UTF8);
            var node = Xml.SelectSingleNode("/d:encryption/d:keyData", _nsm);
            KeyData = new EncryptionKeyData(_nsm, node);
            node = Xml.SelectSingleNode("/d:encryption/d:dataIntegrity", _nsm);
            DataIntegrity = new EncryptionDataIntegrity(_nsm, node);
            KeyEncryptors = new List<EncryptionKeyEncryptor>();

            var list = Xml.SelectNodes("/d:encryption/d:keyEncryptors/d:keyEncryptor/p:encryptedKey", _nsm);
            if (list != null)
            {
                foreach (XmlNode n in list)
                {
                    KeyEncryptors.Add(new EncryptionKeyEncryptor(_nsm, n));
                }
            }

        }
    }
    /// <summary>
    /// Handles the EncryptionInfo stream
    /// </summary>
    internal class EncryptionInfoBinary : EncryptionInfo
    {


        internal Flags Flags;
        internal uint HeaderSize;
        internal EncryptionHeader Header;
        internal EncryptionVerifier Verifier;
        internal override void Read(byte[] data)
        {
            Flags = (Flags)BitConverter.ToInt32(data, 4);
            HeaderSize = (uint)BitConverter.ToInt32(data, 8);

            /**** EncryptionHeader ****/
            Header = new EncryptionHeader();
            Header.Flags = (Flags)BitConverter.ToInt32(data, 12);
            Header.SizeExtra = BitConverter.ToInt32(data, 16);
            Header.AlgID = (AlgorithmID)BitConverter.ToInt32(data, 20);
            Header.AlgIDHash = (AlgorithmHashID)BitConverter.ToInt32(data, 24);
            Header.KeySize = BitConverter.ToInt32(data, 28);
            Header.ProviderType = (ProviderType)BitConverter.ToInt32(data, 32);
            Header.Reserved1 = BitConverter.ToInt32(data, 36);
            Header.Reserved2 = BitConverter.ToInt32(data, 40);

            byte[] text = new byte[(int)HeaderSize - 34];
            Array.Copy(data, 44, text, 0, (int)HeaderSize - 34);
            Header.CSPName = UTF8Encoding.Unicode.GetString(text);

            int pos = (int)HeaderSize + 12;

            /**** EncryptionVerifier ****/
            Verifier = new EncryptionVerifier();
            Verifier.SaltSize = (uint)BitConverter.ToInt32(data, pos);
            Verifier.Salt = new byte[Verifier.SaltSize];

            Array.Copy(data, pos + 4, Verifier.Salt, 0, Verifier.SaltSize);

            Verifier.EncryptedVerifier = new byte[16];
            Array.Copy(data, pos + 20, Verifier.EncryptedVerifier, 0, 16);

            Verifier.VerifierHashSize = (uint)BitConverter.ToInt32(data, pos + 36);
            Verifier.EncryptedVerifierHash = new byte[Verifier.VerifierHashSize];
            Array.Copy(data, pos + 40, Verifier.EncryptedVerifierHash, 0, Verifier.VerifierHashSize);
        }
        internal byte[] WriteBinary()
        {
            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);

            bw.Write(MajorVersion);
            bw.Write(MinorVersion);
            bw.Write((int)Flags);
            byte[] header = Header.WriteBinary();
            bw.Write((uint)header.Length);
            bw.Write(header);
            bw.Write(Verifier.WriteBinary());

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

    }
}
