2009-05-28 4 views
2

Ich habe ein Hilfsmodul implementiert, das es mir ermöglicht, saubere Daten von einem mit SSL verwendeten Kanal zu erhalten und verschlüsselte Daten darin zu schreiben: Dies ist die relevante Schnittstelle (ich habe auch einige nicht abstrakte Methoden in dieser Klasse) , sagt so nicht zu mir, dass „Data Provider sollte eine Schnittstelle sein“;)):SSLEngine und schließen

public abstract class DataProvider { 
    // Notify the bytes read from the net 
    public abstract void readFromNet(ByteBuffer b); 
    // Gets the bytes to write into the net 
    public abstract void writeToNet(ByteBuffer b); 
    // Add a message to send 
    public abstract boolean addMessage(byte[] data); 
    // Obtains the application data received 
    public abstract byte[] getReceivedApplicationData(); 
    // True if there is something to actually send over the wire 
    public abstract boolean dataToSend(); 
    // True if we should close the channel 
    public abstract boolean shouldClose(); 
    // Notify our intention to shut down the connection 
    public abstract void shutDown(SelectionKey sk); 
    // Set the interest op set for the channel 
    public abstract void setInterestOps(SelectionKey sk); 
} 

ich eine Implementierung dieser abstrakten Basisklasse für SSL haben. Während ich diese Implementierung getestet habe, habe ich zwei Funktionen geschrieben: In einem bekomme ich eine Nachricht mit einem SocketChannel und der zum Senden verwendete SSLSocket schließt die Verbindung, in dem anderen sende ich eine Nachricht mit dem SocketChannel den Abschluss damit ein. Nun ist das Problem, dass der SSLSocket verwendet, um die Daten zu empfangen, nicht schließt nicht, auch wenn ich diese Schritte erteilt habe:

  1. engine.closeOutbound()
  2. engine.wrap()
  3. channel.write (Daten) (ja, ich bin sicher, ich habe all Daten mit der Umhüllung()
  4. eine Auswahl des Kanals zum Lesen der eingehenden close_notify

das Problem ist, erhalten gesendet, dass die der Wahlschalter klemmt im 4. Schritt

In dem anderen Test (SSLSocket schließt die Verbindung) habe ich kein Problem.

Bitte beachte, dass ich die shouldClose wie implementiert haben:

return engine.isOutboundDone() && engine.isInboundDone(); 

so brauche ich einen eingehenden close_notify, um zu schließen, auch wenn ich die enge initialisiert haben (ich weiß nicht, ob dies richtig ist : schließlich kann ich es mit return engine.isOutboundDone())

ändern

Das ist mein SSLSocket Seite des Codes ist:

Socket toRead = socket.accept(); 
toRead.setSoTimeout(0); 
InputStream is = toRead.getInputStream(); 
ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
String read = ""; 
byte[] barray = new byte[1024]; 
while (read.length() < toSend.length() * 2) { 
    int bytesRead = is.read(barray); 
    bos.write(barray, 0, bytesRead); 
    read = new String(bos.toByteArray()); 
} 
assertEquals(toSend + toSend, read); 
assertTrue(toRead.isClosed()); 

die letzte assert verletzt wird.

Zunächst dachte ich, dass dies liegt daran, dass ToRead kein "Hintergrund" -Thread zugeordnet ist, also sollte ich einen Lese-/Schreibvorgang mit ihm durchführen, um den eingehenden close_notify zu verbrauchen und dann endlich den Socket zu schließen, aber selbst das hilft nicht.

Irgendeine Idee?

+0

Ich empfehle ernsthaft, dass Sie ein Framework wie Grizzly oder Apache MINA verwenden. Sie mischen verschiedene Programmierparadigmen. –

+2

Was sind diese verschiedenen Programmierparadigmen, die ich zusammen mische? – akappa

Antwort

1

Ich würde empfehlen, is.close(); vor der ersten Behauptung hinzuzufügen.

Bitte beachten Sie, dass dieser kleine Code, den ich vorgeschlagen habe, den Sockel nicht schließt. Es soll den InputStream schließen.

+0

Ich kann den Socket nicht schließen: Ich muss das notify_end des SSL empfangen. – akappa

+0

Wenn Sie den InputStream von Socket schließen, schließen Sie den Kanal. Da die Dokumentation von SSLSocket diese Informationen nicht "überschreibt", nehme ich an, dass der Effekt derselbe ist. Angesichts der Tatsache, dass ich testen möchte, ob ich die SSL-Close in der richtigen Weise implementiert habe, kann ich den SSLSocket nicht schließen, weil ich nur möchte, dass es "für sich selbst" beim Empfang der ssl_close schließt. Ich frage mich, warum es nicht passiert: das ist wirklich meine Frage. – akappa

3

Sehr späte Antwort, aber Sie müssen nicht auf die close_notify warten, wenn Sie bereits eins gesendet haben, siehe RFC 2246. Allerdings sollten Sie einen bekommen. Sie sagen nicht, wie genau Sie bei close_notify auswählen.

Hinweis: Ihr Code ist nicht sinnvoll. Der Socket wird nur geschlossen, wenn Sie schließen. bezieht sich auf den Socket, nicht auf die Verbindung.

Verwandte Themen