﻿/*
 * Copyright 2001-2008 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

using org.apache.juddi.jaxb;
using org.apache.juddi.v3.client.config;
using org.apache.juddi.v3.client.log;
using org.uddi.apiv3;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Xml;

namespace org.apache.juddi.v3.client.cryptor
{
    /// <summary>
    /// A utility class for signing and verifying JAXB Objects, such as UDDI  entities.   
    /// Notes: This class only supports elements that are signed once. 
    /// Multiple signature are not currently supported.
    /// 
    /// Digital signatures can be generated using a standalone PFX file or via the Windows Certificate store
    /// </summary>
    /// <author><a href="mailto:alexoree@apache.org">Alex O'Ree</a></author> 
    public class DigSigUtil
    {
        /// <summary>
        /// creates an uninitialized DigSigUtil, use put to configure
        /// </summary>
        public DigSigUtil()
        {
            map = new Properties();
        }


        /// <summary>
        /// Constructor that will accept a properties set from the juddi config file, or whatever you want
        /// 
        /// </summary>
        /// <param name="c"></param>
        public DigSigUtil(Properties c)
        {
            map = c;
        }

        private Log logger = LogFactory.getLog(typeof(DigSigUtil));

        /// <summary>
        /// added a new key/value to the running config
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void put(String key, String value)
        {
            map.put(key, value);
        }

        /**
         * clears the configuration for reuse
         */
        public void clear()
        {

        }
        private Properties map = new Properties();

        /**
     * This is the location of the keystore
     *
     * If referencing a Windows certificate store, use WINDOWS-MY as a value
     * with a null password
     */
        public readonly static String SIGNATURE_KEYSTORE_FILE = "keyStorePath";
        /**
         * The type of file, such as JKS for most Java applications, or WINDOWS-MY
         * to use the Windows certificate store of the current user or KeychainStore
         * for MacOS
         */
        public readonly static String SIGNATURE_KEYSTORE_FILETYPE = "keyStoreType";
        public readonly static string SIGNATURE_KEYSTORE_FILETYPE_VALUE_PFX = "PFX";
        public readonly static String SIGNATURE_KEYSTORE_FILE_PASSWORD = "filePassword";
        public readonly static String SIGNATURE_KEYSTORE_KEY_PASSWORD = "keyPassword";
        public readonly static String SIGNATURE_KEYSTORE_KEY_ALIAS = "keyAlias";
        public readonly static String TRUSTSTORE_FILE = "trustStorePath";
        public readonly static String TRUSTSTORE_FILETYPE = "trustStoreType";
        public readonly static String TRUSTSTORE_FILE_PASSWORD = "trustStorePassword";
        /**
         * default is CanonicalizationMethod.EXCLUSIVE
         *
         * @see CanonicalizationMethod
         */
        public readonly static String CANONICALIZATIONMETHOD = "CanonicalizationMethod";
        /**
         * default is http://www.w3.org/2000/09/xmldsig#rsa-sha1
         *
         * @see SignatureMethod
         */
        public readonly static String SIGNATURE_METHOD = "SignatureMethod";
        /**
         * Defines whether or not a certificate is included with the signature.
         * Values - Include whole X509 Public Key in the signature (recommended)
         * (default) * Example
         * <example>
         * <code>
         * Map map = new HashMap();
         * map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_BASE64, "true");
         * </code>
         * </example>
         */
        public readonly static String SIGNATURE_OPTION_CERT_INCLUSION_BASE64 = "BASE64";


        /// <summary>
        /// Include the signer's serial of the public key and the issuer's subject name
        /// 
        ///  Clients will not be able to validate the signature unless they have a copy of the signer's public key 
        ///  in a trust store or the full certificate is included
        ///  out of band
        ///      
        ///  Example
        ///  <pre>
        ///  Map map = new HashMap();
        ///  map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SERIAL, "true");</pre>
        ///  any value can be used.
        /// @see SIGNATURE_OPTION_CERT_INCLUSION_BASE64
        /// </summary>
        public readonly static String SIGNATURE_OPTION_CERT_INCLUSION_SERIAL = "SERIAL";
        /*
         * Include the signer's Subject DN of the public key.
         * 
         * Clients will not be able to validate the signature unless they have a copy of the signer's public key 
         * in a trust store or the full certificate is included
         * out of band
         *     
         * Example
         * <pre>
         * Map map = new HashMap();
         * map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN, "true");</pre>
         * any value can be used.
         *@see SIGNATURE_OPTION_CERT_INCLUSION_BASE64
         */
        public readonly static String SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN = "SUBJECTDN";
        /*
         * Include the signer's X500 Prinicple of the public key.
         * 
         * Clients will not be able to validate the signature unless they have a copy of the signer's public key 
         * in a trust store or the full certificate is included
         * out of band
         * <example>    
         * Example
         * <code>
         * Map map = new HashMap();
         * map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_X500_PRINICPAL, "true");
         * </code></example>
         *@see SIGNATURE_OPTION_CERT_INCLUSION_BASE64
         */
        //public readonly static String SIGNATURE_OPTION_CERT_INCLUSION_X500_PRINICPAL = "X500";
        public readonly static String XML_DIGSIG_NS = "http://www.w3.org/2000/09/xmldsig#";
        /**
         * Default value DigestMethod.SHA1 =
         * "http://www.w3.org/2000/09/xmldsig#sha1"
         *
         * @see javax.xml.crypto.dsig.DigestMethod
         */
        public readonly static String SIGNATURE_OPTION_DIGEST_METHOD = "digestMethod";
        /**
         * When validating a signature, include this field will validate that the
         * signature is still valid with regards to timestamps NotBefore and
         * OnOrAfter
         *
         * Example
         * <pre>
         * Map map = new HashMap();
         * map.put(DigSigUtil.CHECK_TIMESTAMPS, true);</pre> any value can be used.
         */
        public readonly static String CHECK_TIMESTAMPS = "checkTimestamps";
        public readonly static String CHECK_REVOCATION_STATUS_OCSP = "checkRevocationOCSP";
        public readonly static String CHECK_REVOCATION_STATUS_CRL = "checkRevocationCRL";
        public readonly static String CHECK_TRUST_CHAIN = "checkTrust";



        /// <summary>
        ///
        /// Verifies the signature on an enveloped digital signature on a UDDI
        /// entity, such as a business, service, tmodel or binding template. 
        /// It is expected that either the public key of the signing certificate is
        /// included within the signature keyinfo section OR that sufficient
        /// information is provided in the signature to reference a public key
        /// located within the Trust Store provided. Optionally, this function
        /// also validate the signing certificate using the options provided to the
        /// configuration map.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="OutErrorMessage"></param>
        /// <returns></returns>
        public bool verifySignedUddiEntity(Object obj, out String OutErrorMessage)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }
            string msg = "";
            //serialize to string
            XmlDocument doc = null;
            if (obj.GetType().Equals(typeof(bindingTemplate)))
            {
                PrintUDDI<bindingTemplate> p = new PrintUDDI<bindingTemplate>();
                String s = p.print(obj);
                doc = StringToXmlDocument(s);
            }
            if (obj.GetType().Equals(typeof(businessService)))
            {
                PrintUDDI<businessService> p = new PrintUDDI<businessService>();
                String s = p.print(obj);
                doc = StringToXmlDocument(s);
            }
            if (obj.GetType().Equals(typeof(businessEntity)))
            {
                PrintUDDI<businessEntity> p = new PrintUDDI<businessEntity>();
                String s = p.print(obj);
                doc = StringToXmlDocument(s);
            }
            if (obj.GetType().Equals(typeof(tModel)))
            {
                PrintUDDI<tModel> p = new PrintUDDI<tModel>();
                String s = p.print(obj);
                doc = StringToXmlDocument(s);
            }

            //get signing certificate 
            X509Certificate2 signingCert = getSigningCertificatePublicKey(doc);

            //check timestamps
            if (map.containsKey(DigSigUtil.CHECK_TIMESTAMPS) && map.getProperty(DigSigUtil.CHECK_TIMESTAMPS).Equals("true", StringComparison.CurrentCultureIgnoreCase))
            {
                if (DateTime.Now < signingCert.NotBefore)
                {
                    msg += "Signing certificate is not yet valid";
                }
                if (DateTime.Now > signingCert.NotAfter)
                {
                    msg += "Signing certificate is not yet valid";
                }
            }
            if (map.containsKey(DigSigUtil.CHECK_TRUST_CHAIN) && map.getProperty(DigSigUtil.CHECK_TRUST_CHAIN).Equals("true", StringComparison.CurrentCultureIgnoreCase))
            {
                //check trust
                X509Chain chain = new X509Chain();
                chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
                bool r = chain.Build(signingCert);
                if (!r)
                {
                    foreach (X509ChainElement element in chain.ChainElements)
                    {
                        msg += ("Element issuer name: " + element.Certificate.Issuer + " is " + element.Certificate.Verify());
                    }
                }
            }
            //check ocsp
            //check crl
            if ((map.containsKey(DigSigUtil.CHECK_REVOCATION_STATUS_OCSP) && map.getProperty(DigSigUtil.CHECK_REVOCATION_STATUS_OCSP).Equals("true", StringComparison.CurrentCultureIgnoreCase)) ||
                (map.containsKey(DigSigUtil.CHECK_REVOCATION_STATUS_CRL) && map.getProperty(DigSigUtil.CHECK_REVOCATION_STATUS_CRL).Equals("true", StringComparison.CurrentCultureIgnoreCase)))
            {
                //check trust
                X509Chain chain = new X509Chain();
                chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
                chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
                bool r = chain.Build(signingCert);
                if (!r)
                {
                    foreach (X509ChainElement element in chain.ChainElements)
                    {
                        msg += ("Element issuer name: " + element.Certificate.Issuer + " is " + element.Certificate.Verify());
                    }
                }
            }


            //verify crypto (math)
            String verifytext = "";
            bool valid = verifySignature(doc, signingCert, out verifytext);
            OutErrorMessage = verifytext + msg;
            return valid;
        }

        private bool verifySignature(XmlDocument Doc, X509Certificate2 cert, out string OutErrorMessage)
        {
            string msg = "";


            // Create a new SignedXml object and pass it 
            // the XML document class.
            SignedXml signedXml = new SignedXml(Doc);

            // Find the "Signature" node and create a new 
            // XmlNodeList object.
            XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");

            // Throw an exception if no signature was found. 
            if (nodeList.Count <= 0)
            {
                msg += ("Verification failed: No Signature was found in the document.");
            }

            // This example only supports one signature for 
            // the entire XML document.  Throw an exception  
            // if more than one signature was found. 
            if (nodeList.Count >= 2)
            {
                msg += ("Verification failed: More that one signature was found for the document.");
            }

            // Load the first <signature> node.  
            signedXml.LoadXml((XmlElement)nodeList[0]);

            // Check the signature and return the result. 
            OutErrorMessage = msg;
            return signedXml.CheckSignature(cert, true);

        }

        private X509Certificate2 getSigningCertificatePublicKey(XmlDocument doc)
        {
            if (doc == null)
                throw new ArgumentNullException("doc");
            XmlNode node = doc.ChildNodes[1];   //this should be the uddi entry
            X509Certificate2 cert = null;
            IEnumerator it = node.ChildNodes.GetEnumerator();
            while (it.MoveNext())
            {
                XmlNode x = (XmlNode)it.Current;
                if (x.NamespaceURI.Equals(DigSigUtil.XML_DIGSIG_NS, StringComparison.CurrentCultureIgnoreCase) &&
                    x.LocalName.Equals("Signature", StringComparison.CurrentCultureIgnoreCase))
                {
                    IEnumerator it2 = x.ChildNodes.GetEnumerator();
                    while (it2.MoveNext())
                    {
                        XmlNode x2 = (XmlNode)it2.Current;
                        if (x2.LocalName.Equals("KeyInfo", StringComparison.CurrentCultureIgnoreCase))
                        {
                            IEnumerator it3 = x2.ChildNodes.GetEnumerator();
                            while (it3.MoveNext())
                            {
                                XmlNode x3 = (XmlNode)it3.Current;
                                if (x3.LocalName.Equals("X509Data", StringComparison.CurrentCultureIgnoreCase))
                                {
                                    //X509Certificate
                                    IEnumerator it4 = x3.ChildNodes.GetEnumerator();
                                    while (it4.MoveNext())
                                    {
                                        XmlNode x4 = (XmlNode)it4.Current;
                                        if (x4.LocalName.Equals("X509Certificate", StringComparison.CurrentCultureIgnoreCase))
                                        {
                                            //X509Certificate
                                            String c =
                                                //"-----BEGIN CERTIFICATE-----\n"
                                                x4.InnerText;
                                            //+ "\n-----END CERTIFICATE-----";

                                            cert = new X509Certificate2(Convert.FromBase64String(c));
                                            logger.info("embedded certificate found, X509 public key " + cert.Subject);
                                            return cert;
                                        }

                                    }
                                }

                            }
                        }

                    }
                }
            }
            return null;
        }

        /// <summary>
        ///  Digitally signs a UDDI entity, such as a business, service, tmodel or
        /// binding template using the map to provide certificate key stores and
        /// credentials. The UDDI entity MUST support XML Digital Signatures
        /// (tModel, Business, Service, Binding Template)
        /// </summary>
        /// <param name="bt"></param>
        /// <returns></returns>
        public object signUddiEntity(object bt)
        {

            XmlDocument doc = null;
            if (bt.GetType().Equals(typeof(bindingTemplate)))
            {
                PrintUDDI<bindingTemplate> p = new PrintUDDI<bindingTemplate>();
                String s = p.print(bt);
                doc = StringToXmlDocument(s);
            }
            if (bt.GetType().Equals(typeof(businessService)))
            {
                PrintUDDI<businessService> p = new PrintUDDI<businessService>();
                String s = p.print(bt);
                doc = StringToXmlDocument(s);
            }
            if (bt.GetType().Equals(typeof(businessEntity)))
            {
                PrintUDDI<businessEntity> p = new PrintUDDI<businessEntity>();
                String s = p.print(bt);
                doc = StringToXmlDocument(s);
            }
            if (bt.GetType().Equals(typeof(tModel)))
            {
                PrintUDDI<tModel> p = new PrintUDDI<tModel>();
                String s = p.print(bt);
                doc = StringToXmlDocument(s);
            }


            X509Certificate2 key = GetKey();
            XmlElement sig = SignXml(doc, key);
            //append the signature to the document
            doc.ChildNodes[1].AppendChild(sig);

            String signedXml = doc.OuterXml;
            if (bt.GetType().Equals(typeof(bindingTemplate)))
            {
                PrintUDDI<bindingTemplate> p = new PrintUDDI<bindingTemplate>();
                return p.createObject(signedXml);
            }
            if (bt.GetType().Equals(typeof(businessService)))
            {
                PrintUDDI<businessService> p = new PrintUDDI<businessService>();
                return p.createObject(signedXml);
            }
            if (bt.GetType().Equals(typeof(businessEntity)))
            {
                PrintUDDI<businessEntity> p = new PrintUDDI<businessEntity>();
                return p.createObject(signedXml);
            }
            if (bt.GetType().Equals(typeof(tModel)))
            {
                PrintUDDI<tModel> p = new PrintUDDI<tModel>();
                return p.createObject(signedXml);
            }
            return bt;
        }


        private X509Certificate2 GetKey()
        {
            
            String storelocation = map.getProperty(DigSigUtil.SIGNATURE_KEYSTORE_FILETYPE);
            if (storelocation.Equals( DigSigUtil.SIGNATURE_KEYSTORE_FILETYPE_VALUE_PFX, StringComparison.CurrentCultureIgnoreCase))
            {
                logger.info("Attempting to load certificate from " + map.getProperty(DigSigUtil.SIGNATURE_KEYSTORE_FILE));
                X509Certificate2 cert = new X509Certificate2(map.getProperty(DigSigUtil.SIGNATURE_KEYSTORE_FILE), 
                    //this should be decrypted already
                    map.getProperty(DigSigUtil.SIGNATURE_KEYSTORE_FILE_PASSWORD));
                return cert;

            }
            String storename = map.getProperty(DigSigUtil.SIGNATURE_KEYSTORE_FILE);
            String keyserial = map.getProperty(DigSigUtil.SIGNATURE_KEYSTORE_KEY_ALIAS);
            
            X509Store store = new X509Store(
                (StoreName)Enum.Parse(typeof(StoreName), storename),
                (StoreLocation)Enum.Parse(typeof(StoreLocation), storelocation));
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Enumerator it = store.Certificates.GetEnumerator();
            while (it.MoveNext())
            {
                X509Certificate2 cert = it.Current;
                if (cert.HasPrivateKey)
                {
                    //do some comparisions
                    if (cert.SerialNumber.Equals(keyserial, StringComparison.CurrentCultureIgnoreCase) ||
                        cert.FriendlyName.Equals(keyserial, StringComparison.CurrentCultureIgnoreCase) ||
                        cert.Subject.Equals(keyserial, StringComparison.CurrentCultureIgnoreCase) ||
                        cert.Thumbprint.Equals(keyserial, StringComparison.CurrentCultureIgnoreCase))
                    {
                        store.Close();
                        return cert;
                    }
                }
            }
            store.Close();
            return null;

        }


        private XmlDocument StringToXmlDocument(String s)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.PreserveWhitespace = false;
            xmlDoc.LoadXml(s);
            return xmlDoc;
        }


        //source http://objectmix.com/dotnet/794749-digitally-sign-xml-doc-x509certificate-solution.html
        //which came from the msdn tutorial

        //Certificate get Signature method
        private XmlElement SignXml(XmlDocument xmlDoc, X509Certificate2 cert)
        {
            //preserve ws - difference here I noticed - mine was set to true
            xmlDoc.PreserveWhitespace = false;

            // Create a SignedXml object.
            SignedXml signedXml = new SignedXml(xmlDoc);

            // Load the certificate into a KeyInfoX509Data object
            // and add it to the KeyInfo object.
            //// Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
            KeyInfo keyInfo = new KeyInfo();
            if (map.getProperty(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_BASE64).Equals("true", StringComparison.CurrentCultureIgnoreCase))
                keyInfo.AddClause(new KeyInfoX509Data(cert));
            if (map.getProperty(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN).Equals("true", StringComparison.CurrentCultureIgnoreCase))
            {
                KeyInfoX509Data data = new KeyInfoX509Data();
                data.AddSubjectName(cert.SubjectName.Name);
                keyInfo.AddClause(data);
            }
            if (map.getProperty(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SERIAL).Equals("true", StringComparison.CurrentCultureIgnoreCase))
            {
                KeyInfoX509Data data = new KeyInfoX509Data();
                data.AddIssuerSerial(cert.IssuerName.Name, cert.SerialNumber);
                keyInfo.AddClause(data);
            }

            signedXml.KeyInfo = keyInfo;

            //CANON method
            signedXml.SignedInfo.CanonicalizationMethod = map.getProperty(DigSigUtil.CANONICALIZATIONMETHOD);
            if (String.IsNullOrEmpty(signedXml.SignedInfo.CanonicalizationMethod))
                signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NWithCommentsTransformUrl;

            signedXml.SignedInfo.SignatureMethod = map.getProperty(DigSigUtil.SIGNATURE_METHOD);
            if (String.IsNullOrEmpty(signedXml.SignedInfo.SignatureMethod))
                signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;


            // Set the rsaKey to the certificate's private key
            RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)cert.PrivateKey;

            // Add the key to the SignedXml document.
            signedXml.SigningKey = rsaKey;

            // Create a reference to be signed.
            Reference reference = new Reference();
            reference.Uri = "";

            // Add an enveloped transformation to the reference.
            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
            reference.AddTransform(env);


            // Add the reference to the SignedXml object.
            signedXml.AddReference(reference);

            // Now we can compute the signature.
            signedXml.ComputeSignature();
            return signedXml.GetXml();
            //   return signedXml;

        }

        //gets payload data and returns xmn XMLDocument
        private XmlDocument GetPayLoadData(string xmlstring)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xmlstring);
            return xmlDoc;

        }
    }
}
