public static string Convert(Stream pemData)
        {
            var  pemObject = new PemReader(new StreamReader(pemData)).ReadObject();
            RSA  key;
            bool isPrivate;

            if (pemObject is AsymmetricCipherKeyPair)
            {
                isPrivate = true;
                var privateKeyParams = ((AsymmetricCipherKeyPair)pemObject).Private;
                key = DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)privateKeyParams);
            }
            else if (pemObject is RsaKeyParameters)
            {
                isPrivate = false;
                key       = DotNetUtilities.ToRSA((RsaKeyParameters)pemObject);
            }
            else
            {
                throw new ArgumentException("object is not PEM encoded RSA key " +
                                            $"(decoded: {pemObject.GetType().Name})",
                                            nameof(pemData));
            }
            return(RsaKeyLoader.ToXmlString(key, isPrivate));
        }
        public static string SignData(string data, string privateKeyPath = "private-key.xml")
        {
            var privateKey = RsaKeyLoader.FromXmlFile(privateKeyPath);
            var signature  = privateKey.SignData(PaymentHandler.DigestEncoding.GetBytes(data),
                                                 PaymentHandler.HashAlgorithm,
                                                 PaymentHandler.SignaturePadding);

            return(Convert.ToBase64String(signature));
        }
        public static async Task <string> SendRequest(
            string accountKey,
            PaymentHandler.Gateway gateway,
            string payloadPath    = "payload.xml",
            string privateKeyPath = "private-key.xml",
            string hostname       = "paymentapi.contact-world.net")
        {
            var payload    = File.ReadAllText(payloadPath).Trim();
            var privateKey = RsaKeyLoader.FromXmlFile(privateKeyPath);
            var handler    = new PaymentHandler(accountKey, gateway, hostname, privateKey, TimeSpan.FromSeconds(1));

            return(await handler.MakePayment(payload, Console.WriteLine));
        }
        public static bool VerifySignature(string signatureBase64,
                                           string data,
                                           string publicKeyPath = "public-key.xml")
        {
            var publicKey = RsaKeyLoader.FromXmlFile(publicKeyPath);
            var signature = Convert.FromBase64String(signatureBase64);
            var dataBytes = PaymentHandler.DigestEncoding.GetBytes(data);

            return(publicKey.VerifyData(dataBytes,
                                        signature,
                                        PaymentHandler.HashAlgorithm,
                                        PaymentHandler.SignaturePadding));
        }
        public static string GenerateKeys(string privateKeyPath = "private-key.xml",
                                          string publicKeyPath  = "public-key.xml")
        {
            var key = RSA.Create();

            key.KeySize = PaymentHandler.KeySize;
            File.WriteAllText(privateKeyPath, RsaKeyLoader.ToXmlString(key, includePrivateParameters: true));
            File.WriteAllText(publicKeyPath, RsaKeyLoader.ToXmlString(key, includePrivateParameters: false));

            return($"Files written to {Path.GetDirectoryName(Path.GetFullPath(privateKeyPath))}\n" +
                   $"	{privateKeyPath}: keep this one secure and never pass to anyone\n"+
                   $"	{publicKeyPath}:  pass this one to NewVoiceMedia operations");
        }
        public static bool CheckKeys(
            string privateKeyPath = "private-key.xml",
            string publicKeyPath  = "public-key.xml")
        {
            var privateKey = RsaKeyLoader.FromXmlFile(privateKeyPath);
            var publicKey  = RsaKeyLoader.FromXmlFile(publicKeyPath);
            var testData   = PaymentHandler.DigestEncoding.GetBytes("NewVoiceMedia Rulezzz");
            var signature  = privateKey.SignData(testData,
                                                 PaymentHandler.HashAlgorithm,
                                                 PaymentHandler.SignaturePadding);

            return(publicKey.VerifyData(testData,
                                        signature,
                                        PaymentHandler.HashAlgorithm,
                                        PaymentHandler.SignaturePadding));
        }
        public static async Task <string> RelayRequest(
            string accountKey,
            PaymentHandler.Gateway gateway,
            string privateKeyPath = "private-key.xml",
            string hostname       = "paymentapi.contact-world.net")
        {
            var    payload = new StringBuilder();
            string line;

            while ((line = Console.ReadLine()) != null)
            {
                payload.AppendLine(line);
            }
            var privateKey = RsaKeyLoader.FromXmlFile(privateKeyPath);
            var handler    = new PaymentHandler(accountKey, gateway, hostname, privateKey, TimeSpan.FromSeconds(1));

            return(await handler.MakePayment(payload.ToString(), Console.WriteLine));
        }