2013-03-19 11 views
26

Wiem, że jest on rzadko używany, ale czy można uzyskać dostęp do certyfikatu klienta w Snap?Jak mogę sprawdzić certyfikat klienta za pomocą Snap'a

Jeśli nie, czy jest to możliwe przy użyciu innego stosu internetowego?

+1

Bardziej ogólnie, chciałbym wiedzieć, czy jakikolwiek framework sieciowy Haskell zapewnia obsługę uwierzytelniania klienta opartego na certyfikatach. –

+0

To nie jest odpowiedź, ale jako obejście można użyć nginx do weryfikacji certyfikatów i przekazania nazwy wyróżniającej przez nagłówek. –

Odpowiedz

1

To nie jest dostępne dla Ciebie w pakiecie Snap snap-server, co zakładam, że używasz swojego serwera.

Buuuuut nie jest trudny do zbudowania, albo przez rozwidlenie, albo jako osobny moduł (będziesz musiał skopiować jakiś kod, ponieważ niektóre wewnętrzne wartości, których potrzebujesz, nie są eksportowane). bindHttps, located in Snap.Internal.Http.Server.TLS, jest to, na co chcesz kierować. Ta funkcja jest w dużej mierze opakowaniem wywołań do OpenSSL.Session z biblioteki HsOpenSSL, która sama jest luźnym opakowaniem w bibliotece OpenSSL.

Na szczęście dla nas OpenSSL ma pełną obsługę certyfikatów klienta. Po prostu musisz ustawić verification mode na SSL_VERIFY_PEER. Są jeszcze inne gałki, którymi możesz się bawić. Musisz także upewnić się, że zainstalowałeś łańcuch certyfikatów, aby faktycznie zweryfikować certyfikat klienta. Łańcuch zaufania i cały ten jazz. Dla odniesienia zobacz, jak nginx does it.

Jeszcze lepiej, ta funkcja to exposed w HsOpenSSL jako funkcja contextSetVerificationMode :: SSLContext -> VerificationMode -> IO(). Zauważysz, że ctx :: SSLContext istnieje w definicji Snap'a bindHttps. Wszystko, co musisz zrobić, to skopiować lub rozwidlić ten moduł i wprowadzić swoje połączenia.

To będzie wyglądał tak (alert kodu niezweryfikowany):

± % diff -u /tmp/{old,new} 
--- /tmp/old 2016-04-11 11:02:42.000000000 -0400 
+++ /tmp/new 2016-04-11 11:02:56.000000000 -0400 
@@ -19,6 +19,7 @@ 

     ctx <- SSL.context 
     SSL.contextSetPrivateKeyFile ctx key 
+  SSL.contextSetVerificationMode ctx (SSL.VerifyPeer True True (Just (\_ _ -> return True))) 
     if chainCert 
     then SSL.contextSetCertificateChainFile ctx cert 
     else SSL.contextSetCertificateFile ctx cert 

Pierwszy logiczna mówi OpenSSL na niepowodzenie, jeśli klient nie jest obecny certyfikat. Druga wartość boolowska mówi OpenSSL, że certyfikat klienta jest potrzebny tylko na pierwsze żądanie i nie jest już potrzebny w przypadku renegocjacji. Trzecią wartością jest wywołanie zwrotne. Myślę, że właściwym rozwiązaniem jest zwrócenie True w wywołaniu zwrotnym. W każdym razie to jest nginx does.

Powiązane problemy