diff --git a/NOnion/Exceptions.fs b/NOnion/Exceptions.fs index 4cd21ff8..3a9427bb 100644 --- a/NOnion/Exceptions.fs +++ b/NOnion/Exceptions.fs @@ -26,6 +26,12 @@ type CircuitTruncatedException internal (reason: DestroyReason) = type CircuitDestroyedException internal (reason: DestroyReason) = inherit NOnionException(sprintf "Circuit got destroyed, reason %A" reason) +type CircuitDecryptionFailedException internal () = + inherit NOnionException(sprintf "Circuit Decryption Failed") + +type HandshakeFailedException internal () = + inherit NOnionException(sprintf "Key handshake failed!") + type TimeoutErrorException internal () = inherit NOnionException("Time limit exceeded for operation") diff --git a/NOnion/Network/TorCircuit.fs b/NOnion/Network/TorCircuit.fs index 57c9f691..77748073 100644 --- a/NOnion/Network/TorCircuit.fs +++ b/NOnion/Network/TorCircuit.fs @@ -336,7 +336,8 @@ and TorCircuit node) | None -> announceDeath() - failwith "Decryption failed!" + + raise <| CircuitDecryptionFailedException() decryptMessage encryptedRelayCell.EncryptedData nodes | _ -> failwith "Unexpected state when receiving relay cell" diff --git a/NOnion/Network/TorGuard.fs b/NOnion/Network/TorGuard.fs index d32e9584..b5e90d4f 100644 --- a/NOnion/Network/TorGuard.fs +++ b/NOnion/Network/TorGuard.fs @@ -193,6 +193,18 @@ type TorGuard private (client: TcpClient, sslStream: SslStream) = member self.SendAsync (circuidId: uint16) (cellToSend: ICell) = self.Send circuidId cellToSend |> Async.StartAsTask + member private self.HandleIncomingCellException<'T when 'T :> NOnionException> + (cell: ICell) + (ex: 'T) + = + sprintf + "TorGuard: exception when trying to handle incoming cell type=%i, ex=%s" + cell.Command + (ex.ToString()) + |> TorLogger.Log + + self.KillChildCircuits() + member private __.ReceiveInternal() = async { (* @@ -332,14 +344,15 @@ type TorGuard private (client: TcpClient, sslStream: SslStream) = try do! circuit.HandleIncomingCell cell with - | ex -> - sprintf - "TorGuard: exception when trying to handle incoming cell type=%i, ex=%s" - cell.Command - (ex.ToString()) - |> TorLogger.Log - - self.KillChildCircuits() + | :? HandshakeFailedException as ex -> + self.HandleIncomingCellException + cell + ex + | :? CircuitDecryptionFailedException as ex -> + self.HandleIncomingCellException + cell + ex + | ex -> return raise <| FSharpUtil.ReRaise ex | None -> self.KillChildCircuits() failwithf "Unknown circuit, Id = %i" cid diff --git a/NOnion/TorHandshakes/FastHandshake.fs b/NOnion/TorHandshakes/FastHandshake.fs index bc2fe4ee..173072ee 100644 --- a/NOnion/TorHandshakes/FastHandshake.fs +++ b/NOnion/TorHandshakes/FastHandshake.fs @@ -36,6 +36,6 @@ type FastHandshake = |> Kdf.ComputeLegacyKdf if kdfResult.KeyHandshake <> serverSideData.DerivativeKey then - failwith "Key handshake failed!" + raise <| HandshakeFailedException() else kdfResult diff --git a/NOnion/TorHandshakes/NTorHandshake.fs b/NOnion/TorHandshakes/NTorHandshake.fs index 9f88a43a..0564acb5 100644 --- a/NOnion/TorHandshakes/NTorHandshake.fs +++ b/NOnion/TorHandshakes/NTorHandshake.fs @@ -107,6 +107,6 @@ type NTorHandshake = let auth = calculateHmacSha256 authInput Constants.NTorTMac if auth <> serverSideData.DerivativeKey then - failwith "Key handshake failed!" + raise <| HandshakeFailedException() else Kdf.ComputeRfc5869Kdf secretInput