Certificate verification with Cordova - authentication

I wonder if there is a simple/recommended way for verifying the remote site certificate within Cordova. I would like my app to verify $remote.thumbprint is in a list of expected thumbprints and no one MITMs. The code (and the list) should be deployed on the phone through the app stores (I just assume they are trusted).
Preferably a straight forward solution that does not require platform specific code for Android, IOS and WP?

In order to see the cert information on a remote site you have to have access to that remote server. But assuming you have access to the server you could write some server code that returns a list of thumbrint values and what ever else you may need returned. Here is how you could do it with C# using asp.net:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.IO;
using System.Security.Cryptography.X509Certificates;
namespace FIPWS01
{
public partial class certtest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
// X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindBySubjectName, "Kilpatrick", false);
X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindBySubjectName, "[your info here]", false);
Response.Write("Number of certificates: " + fcollection.Count + "<br>");
foreach (X509Certificate2 x509 in fcollection)
{
byte[] rawdata = x509.RawData;
Response.Write("Friendly Name: " + x509.FriendlyName + "<br>");
Response.Write("Simple Name: " + x509.GetNameInfo(X509NameType.SimpleName, true) + "<br>");
Response.Write("Thumb Print: " + x509.Thumbprint + "<br>");
}
store.Close();
}
catch (CryptographicException)
{
Response.Write("Information could not be written out for this certificate.");
}
}
}
}

Related

List of folder not shared with me, Google Drive API

In my application, I want to list all folder that exist in my drive, but I don't know how to do it. I want to list folder just in "My Drive" not in "Shared with me".
Here is my code :
Dim fold = Service.Files.List()
fold.Q = "mimeType = 'application/vnd.google-apps.folder' and trashed = false and 'me' in owners "
But I have an exception: Invalid Query [400]
You can refer to this documentation.
Also, the includeTeamDriveItems was already set to false as a default value. From here, you will be able to set if you want to include team drives in the result.
Try the code from the quickstart.
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Drive.v3.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace DriveQuickstart
{
class Program
{
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/drive-dotnet-quickstart.json
static string[] Scopes = { DriveService.Scope.DriveReadonly };
static string ApplicationName = "Drive API .NET Quickstart";
static void Main(string[] args)
{
UserCredential credential;
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/drive-dotnet-quickstart.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Drive API service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
FilesResource.ListRequest listRequest = service.Files.List();
listRequest.PageSize = 10;
listRequest.Fields = "nextPageToken, files(id, name)";
// List files.
IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute()
.Files;
Console.WriteLine("Files:");
if (files != null && files.Count > 0)
{
foreach (var file in files)
{
Console.WriteLine("{0} ({1})", file.Name, file.Id);
}
}
else
{
Console.WriteLine("No files found.");
}
Console.Read();
}
}
}
Regarding your error, I think you are trying to use search parameters specific for two different versions, Drive v3 API and Drive v2 API
You can refer to this SO post for further information.

How to pass client certificate using AutoRest client

We are using AutoRest for generating client code based on API Swagger files.
I'm trying to pass client certificate to the API. But noticed that generated client code doesn't accept WebRequestHandler.
Generated code looks like below:
public MyTestApiV1(Uri baseUri, params DelegatingHandler[] handlers) : this(handlers)
{
if (baseUri == null)
{
throw new ArgumentNullException("baseUri");
}
this.BaseUri = baseUri;
}
I feel like I'm missing something here. Has anyone managed to send client certificate using AutoRest?
Tried this but webRequestHandler is always null:
var webRequestHandler = client.HttpMessageHandlers.First() as WebRequestHandler;
if (webRequestHandler != null)
{
var secretRetrieved = keyVault.GetSecretAsync("my-cert");
var pfxBytes = Convert.FromBase64String(secretRetrieved.Result);
// or recreate the certificate directly
var certificate = new X509Certificate2(pfxBytes);
webRequestHandler.ClientCertificates.Add(certificate);
}
You can use another overloaded constructor:
/// <summary>
/// Initializes ServiceClient using base HttpClientHandler and list of handlers.
/// </summary>
/// <param name="rootHandler">Base HttpClientHandler.</param>
/// <param name="handlers">List of handlers from top to bottom (outer handler is the first in the list)</param>
protected ServiceClient(HttpClientHandler rootHandler, params DelegatingHandler[] handlers)
ServiceClient is the base class for generated clients. Therefore, code might look like:
var secretRetrieved = keyVault.GetSecretAsync("my-cert");
var pfxBytes = Convert.FromBase64String(secretRetrieved.Result);
// or recreate the certificate directly
var certificate = new X509Certificate2(pfxBytes);
WebRequestHandler webRequestHandler = new WebRequestHandler();
webRequestHandler.ClientCertificates.Add(certificate);
var client = new MyTestApiV1(webRequestHandler);
client.BaseUri = baseUri;
.net Core version
Ivan R's answer led me on the right path but it's a little different for .net core (2.2 at this point in time) as WebRequestHandler is not available in core.
I had to use a pfx file and password in my case. GetNumberPassedIn isn't in the generic Petstore Swagger template but was what I was testing with.
Program.cs:
using System;
using System.Net.Http;
namespace SimpleApi2.Console
{
class Program
{
static void Main(string[] args)
{
var certificate = new CertInfo().GetCertFromPfx(Const.PfxPath, Const.PfxPassword);
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(certificate);
var client = new HttpClient(handler);
var petStore = new SwaggerPetstore(client, true);
petStore.BaseUri = new Uri(Const.PublicUrl);
var result = petStore.GetNumberPassedIn(135, Const.ApiKey);
System.Console.WriteLine(result.ToString());
System.Console.ReadKey();
}
}
}
CertInfo.cs:
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Security;
namespace SimpleApi2.Console
{
class CertInfo
{
internal static byte[] ReadFile(string fileName)
{
FileStream f = new FileStream(fileName, FileMode.Open, FileAccess.Read);
int size = (int)f.Length;
byte[] data = new byte[size];
f.Read(data, 0, size);
f.Close();
return data;
}
public CertInfo() { }
public X509Certificate2 GetCertFromPfx(string pfxFilePath, string password)
{
try
{
byte[] rawData = ReadFile(pfxFilePath);
var passwordAsChars = password.ToCharArray();
var securePassword = new SecureString();
foreach (char c in password)
securePassword.AppendChar(c);
securePassword.MakeReadOnly();
X509Certificate2 x509 = new X509Certificate2(pfxFilePath, password,
X509KeyStorageFlags.UserKeySet);
WriteCertInfo(x509);
return x509;
}
catch (DirectoryNotFoundException)
{
System.Console.WriteLine("Error: The directory specified could not be found.");
throw;
}
catch (IOException)
{
System.Console.WriteLine("Error: A file in the directory could not be accessed.");
throw;
}
catch (NullReferenceException)
{
System.Console.WriteLine("File must be a .cer file. Program does not have access to that type of file.");
throw;
}
}
private static void WriteCertInfo(X509Certificate2 x509)
{
//Print to console information contained in the certificate.
System.Console.WriteLine("{0}Subject: {1}{0}", Environment.NewLine, x509.Subject);
System.Console.WriteLine("{0}Issuer: {1}{0}", Environment.NewLine, x509.Issuer);
System.Console.WriteLine("{0}Version: {1}{0}", Environment.NewLine, x509.Version);
System.Console.WriteLine("{0}Valid Date: {1}{0}", Environment.NewLine, x509.NotBefore);
System.Console.WriteLine("{0}Expiry Date: {1}{0}", Environment.NewLine, x509.NotAfter);
System.Console.WriteLine("{0}Thumbprint: {1}{0}", Environment.NewLine, x509.Thumbprint);
System.Console.WriteLine("{0}Serial Number: {1}{0}", Environment.NewLine, x509.SerialNumber);
System.Console.WriteLine("{0}Friendly Name: {1}{0}", Environment.NewLine, x509.PublicKey.Oid.FriendlyName);
System.Console.WriteLine("{0}Public Key Format: {1}{0}", Environment.NewLine, x509.PublicKey.EncodedKeyValue.Format(true));
System.Console.WriteLine("{0}Raw Data Length: {1}{0}", Environment.NewLine, x509.RawData.Length);
System.Console.WriteLine("{0}Certificate to string: {1}{0}", Environment.NewLine, x509.ToString(true));
}
}
}

SQL Server 2016 RC1 : Unable to debug SSIS package

I installed SQL server 2016 RC1 in Windows 10 (formatted and installed the OS). I first installed VS2015 with latest updates and then the SQL. I am not able to debug the SSIS packages and I get following error.
Method 'SaveAndUpdateVersionToXML' in type 'Microsoft.DataTransformationServices.Project.DebugEngine.InterfaceWrappers.Sql2014ApplicationClassWrapper' from assembly 'Microsoft.DataTransformationServices.VsIntegration, Version=13.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' does not have an implementation. (Microsoft Visual Studio)
I installed the latest version of SQL Server Data Tools
Is anyone facing similar issue? Any solution for this problem?
to run the package you might wana use this c# solution:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using dts1=Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.Timers;
using System.Threading;
using ustimer=System.Windows.Forms;
namespace integration
{
public partial class integration : Form
{
public integration()
{
InitializeComponent();
}
public int c = 0;
public string path = #"c:\users\Package.dtsx";
private void button1_Click(object sender, EventArgs e)
{
dts1.IDTSPackage100 pkg;
dts1.IDTSApplication100 app;
dts1.DTSExecResult pkgResults;
app = new dts1.Application();
pkg = app.LoadPackage(path, true, null);
try
{
pkgResults = pkg.Execute(null, null, null, null, null);
if (pkgResults == dts1.DTSExecResult.DTSER_SUCCESS)
{
MessageBox.Show("works");
}
else
{
MessageBox.Show("failed");
}
}
catch
{
//
}
}
public void run_pkg(string path, bool feedback = true)
{
dts1.IDTSPackage100 pkg;
dts1.IDTSApplication100 app;
dts1.DTSExecResult pkgResults;
app = new dts1.Application();
pkg = app.LoadPackage(path, true, null);
try
{
pkgResults = pkg.Execute(null, null, null, null, null);
if (feedback == true)
{
if (pkgResults == dts1.DTSExecResult.DTSER_SUCCESS)
{ MessageBox.Show("worked"); }
else
{ MessageBox.Show("failed"); }
}
}
catch
{
//
}
}}
This update fixed the issue for me: https://blogs.msdn.microsoft.com/ssdt/2016/04/05/ssdt-preview-update-rc2/

Is it possible to query public Big Query Data Sets using scripts without registering for billing

Is it possible to query public Big Query Data Sets such as https://www.githubarchive.org/ using C#/python scripts without registering for billing on Google Big Query. I have used the C# code attached but it gives me Insufficient Permission [403] error
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using DotNetOpenAuth.OAuth2;
using Google.Apis.Bigquery.v2;
using Google.Apis.Bigquery.v2.Data;
using Google.Apis.Util;
namespace BQTry
{
public class BigQueryConsole
{
static string query = "SELECT count(*) FROM [githubarchive:year.2014]";
static string projectId = "some project id";
public static void Main(string[] args)
{
Console.WriteLine("BigQueryAPI STARTINg");
Console.WriteLine("==========================");
String serviceAccountEmail = "someaccount#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"G:\CW and Research\TERM 2\SM\PROJECT\Code\BQTry\key\somekye.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { BigqueryService.Scope.DevstorageReadOnly }
}.FromCertificate(certificate));
// Create the service.
var service = new BigqueryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "BigQuery API Sample",
});
//Note: all your requests will run against Service.
JobsResource j = service.Jobs;
QueryRequest qr = new QueryRequest();
qr.Query = query;
QueryResponse response = j.Query(qr, projectId).Execute();
}
}
}
No matter what you do, you will need to enable billing, or send the credentials from a project that did.
So quick answer to your question : no. You will need to enable billing. Doesn't mean that, if all you do is query the public datasets, you'll pay.
As indicated here and in the linked docs on this page, the first TB of processed data each month is free.

Emailing from monodevelop .vs. VS2013

I am attempting to email a small report once a larger process is done running. The email code runs fine under windows 8.1 from VS2013, however when i move the code over to mono under Ubuntu(13.10) it gives the error --
ERROR 535 5.7.8 Error: Authentication failed: UGFzc3dvcmQ6
-- What's puzzling to me is that if there is an Authentication failure under ubuntu/linux shouldn't the same Authentication failure be occurring under windows 8.1. The email server is one which my company runs(not gmail.com/live.com/etc). Any help would be great, thanks in advance.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Mail;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using S22.Imap;
using S22;
namespace testing_email {
class Program {
static void Main(string[] args) {
SmtpClient client = new SmtpClient("mail.XXXXXX.com");
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("myreportuser#XXXXX.com", "password");
client.Port = 25;
client.EnableSsl = true;
MailMessage mailit = new MailMessage();
mailit.Body = "Body body body";
mailit.Subject = "Testing Subject";
mailit.IsBodyHtml = true;
mailit.From = new MailAddress("myreportuser#XXXXXX.com");
mailit.To.Add("l.send.it#XXXXX.com");
try {
ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
client.Send(mailit);
Console.WriteLine("Message sent");
Console.ReadLine();
}
catch (Exception ex) {
Console.WriteLine("ERROR " + ex.Message);
Console.ReadLine();
}
}
}
}