using System;
using System.Text;
using System.Diagnostics;
using CryptoSysPKI;

$Id: Xmldsig2.cs $
$Date: 2017/03/20 22:01 $

Copyright (C) 2017 DI Management Services Pty Ltd. All rights reserved.

References: Signing an XML document using XMLDSIG (Part 2) Creating output for secure XML documents


namespace Xmldsig2
    class Xmldsig2
        static void Main(string[] args)
            string digval, sigval, keyval;
            string pfxfile, keyfile, certfile;
            string pubkey;
            StringBuilder sbPassword, sbPrikey;
            int keyhash1, keyhash2;
            int r;

            Console.WriteLine("PKI Version={0}", General.Version());

            // All data files assumed to be in current working directory

            // Store password in StringBuilder so we can erase it later
            sbPassword = new StringBuilder("password");

            // 0. Extract PKCS#8 private key file and X.509 certificate from PFX file
            pfxfile = "alice.pfx";
            keyfile = "alice.key";
            r = Rsa.GetPrivateKeyFromPFX(keyfile, pfxfile);
            Debug.Assert(r > 0, "PFX file is invalid or missing");
            Console.WriteLine("Extracted keyfile '{0}' from PFX", keyfile);
            certfile = "alice.cer";
            r = X509.GetCertFromPFX(certfile, pfxfile, sbPassword.ToString());
            Debug.Assert(r > 0, "PFX file or its password is invalid");
            Console.WriteLine("Extracted certfile '{0}' from PFX", certfile);

            Console.WriteLine("Show we can read the two files we just extracted...");
            pubkey = Rsa.ReadPublicKey(certfile).ToString();
            keyhash1 = Rsa.KeyHashCode(pubkey);
            Console.WriteLine("Public key is  {0} bits long with key hashcode {1,8:X}", Rsa.KeyBits(pubkey), keyhash1);
            sbPrikey = Rsa.ReadPrivateKey(keyfile, sbPassword.ToString());
            keyhash2 = Rsa.KeyHashCode(sbPrikey.ToString());
            Console.WriteLine("Private key is {0} bits long with key hashcode {1,8:X}", Rsa.KeyBits(sbPrikey.ToString()), keyhash2);

            // 1. Compute SHA-1 digest value of canonicalized XML
            // Ref:
            Console.WriteLine("\nCompute digest value of c14n'd document:");
            digval = Cnv.ToBase64(Hash.BytesFromFile("enveloped-c14n.xml", HashAlgorithm.Sha1));
            Console.WriteLine("DigestValue: " + digval);

            // 2. Compute signature value of canonicalized SignedInfo
            Console.WriteLine("\nCompute signature value from c14n'd SignedInfo:");
            sigval = Sig.SignFile("enveloped-signedinfo.xml", keyfile, sbPassword.ToString(), SigAlgorithm.Rsa_Sha1);

            // 3. Extract RSAKeyValue from X.509 certificate via internal key string
            Console.WriteLine("\nExtract RSAKeyValue from X.509 certificate:");
            pubkey = Rsa.ReadPublicKey(certfile).ToString();
            Debug.Assert(pubkey.Length > 0);
            keyval = Rsa.ToXMLString(pubkey, 0);

            // 4. Clean up sensitive data