public static ByteArrayComparer Default() { if (staticDefault == null) { staticDefault = new ByteArrayComparer(); } return(staticDefault); }
private IoScheduler(PrivateIdentity myIdentity, string localHostNameOrAddress, int localPort, List <PublicIdentity> knownIdentities, bool i_verbose = false, int i_maxSendTries = 3) { verbose = i_verbose; maxSendTries = i_maxSendTries; receiveQueue = new BufferBlock <ReceivedPacket>(); destinationPublicKeyToSenderThreadMap = new Dictionary <byte[], List <SenderThread> >(ByteArrayComparer.Default()); publicKeyToPublicIdentityMap = new Dictionary <byte[], PublicIdentity>(ByteArrayComparer.Default()); foreach (var knownIdentity in knownIdentities) { publicKeyToPublicIdentityMap[knownIdentity.PublicKey] = knownIdentity; } if (myIdentity == null) { StartClient(); } else { StartServer(myIdentity, localHostNameOrAddress, localPort); } }
protected override bool Connect() { var destinationPublicIdentity = scheduler.LookupPublicKey(destinationPublicKey); if (destinationPublicIdentity == null) { if (scheduler.Verbose) { Console.Error.WriteLine("Could not connect to destination public key {0} because we don't know its address.", IoScheduler.PublicKeyToString(destinationPublicKey)); } return(false); } if (scheduler.Verbose) { Console.WriteLine("Starting connection to {0}", IoScheduler.PublicIdentityToString(destinationPublicIdentity)); } TcpClient client; try { client = new TcpClient(destinationPublicIdentity.HostNameOrAddress, destinationPublicIdentity.Port); } catch (Exception e) { scheduler.ReportException(e, "connecting to " + IoScheduler.PublicIdentityToString(destinationPublicIdentity)); return(false); } var myCertificateCollection = new X509CertificateCollection(); myCertificateCollection.Add(scheduler.MyCert); var myValidator = new CertificateValidator(scheduler, destinationPublicIdentity); try { stream = new SslStream(client.GetStream(), leaveInnerStreamOpen: false, myValidator.ValidateSSLCertificate); stream.AuthenticateAsClient(destinationPublicIdentity.FriendlyName, myCertificateCollection, checkCertificateRevocation: false); } catch (Exception e) { scheduler.ReportException(e, "authenticating connection to " + IoScheduler.PublicIdentityToString(destinationPublicIdentity)); return(false); } remoteCert = stream.RemoteCertificate as X509Certificate2; if (!ByteArrayComparer.Default().Equals(IoScheduler.GetCertificatePublicKey(remoteCert), destinationPublicKey)) { Console.Error.WriteLine("Connected to {0} expecting public key {1} but found public key {2}, so disconnecting.", IoScheduler.PublicIdentityToString(destinationPublicIdentity), IoScheduler.PublicKeyToString(destinationPublicKey), IoScheduler.PublicKeyToString(IoScheduler.GetCertificatePublicKey(remoteCert))); return(false); } if (scheduler.Verbose) { Console.WriteLine("Successfully connected to {0} and got certificate identifying it as {1}", IoScheduler.PublicIdentityToString(destinationPublicIdentity), IoScheduler.CertificateToString(remoteCert)); } // Now that the connection is successful, create a thread to // receive packets on it. ReceiverThread receiverThread = ReceiverThread.Create(scheduler, stream); return(true); }
public bool ValidateSSLCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { const SslPolicyErrors ignoredErrors = SslPolicyErrors.RemoteCertificateChainErrors; if ((sslPolicyErrors & ~ignoredErrors) != SslPolicyErrors.None) { Console.Error.WriteLine("Could not validate SSL certificate for {0} due to errors {1}", IoScheduler.GetCertificatePublicKey(certificate as X509Certificate2), sslPolicyErrors & ~ignoredErrors); return(false); } var cert2 = certificate as X509Certificate2; // If we were expecting a specific public identity, check that // the key in the certificate matches what we were expecting. if (expectedPublicIdentity != null) { if (!ByteArrayComparer.Default().Equals(IoScheduler.GetCertificatePublicKey(cert2), expectedPublicIdentity.PublicKey)) { Console.Error.WriteLine("Connected to {0} expecting public key {1} but found public key {2}, so disconnecting.", IoScheduler.PublicIdentityToString(expectedPublicIdentity), IoScheduler.PublicKeyToString(expectedPublicIdentity.PublicKey), IoScheduler.PublicKeyToString(IoScheduler.GetCertificatePublicKey(cert2))); return(false); } if (cert2.SubjectName.Name != "CN=" + expectedPublicIdentity.FriendlyName) { Console.Error.WriteLine("Connected to {0} expecting subject CN={1} but found {2}, so disconnecting.", IoScheduler.PublicIdentityToString(expectedPublicIdentity), expectedPublicIdentity.FriendlyName, cert2.SubjectName.Name); return(false); } } else { // If we weren't expecting any particular public identity, // consider the expected public identity to be the known one // matching the public key in the certificate we got. If // there is no known one, then this is just an anonymous // client, which is fine. Otherwise, check that the subject // matches what we expect. This is just a paranoid check; it // should never fail. expectedPublicIdentity = scheduler.LookupPublicKey(IoScheduler.GetCertificatePublicKey(cert2)); if (expectedPublicIdentity != null) { if (cert2.SubjectName.Name != "CN=" + expectedPublicIdentity.FriendlyName) { Console.Error.WriteLine("Received a certificate we expected to have subject CN={1} but found {2}, so disconnecting.", IoScheduler.PublicIdentityToString(expectedPublicIdentity), expectedPublicIdentity.FriendlyName, cert2.SubjectName.Name); return(false); } } } return(true); }