mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
The error we're looking for is "certificate verify failed". The routine that reports this will be different between openssl versions, so it makes no sense to track the routine name as well.
131 lines
3.5 KiB
Nim
131 lines
3.5 KiB
Nim
discard """
|
|
cmd: "nim $target --threads:on -d:ssl $options $file"
|
|
disabled: "openbsd"
|
|
"""
|
|
|
|
# Nim - Basic SSL integration tests
|
|
# (c) Copyright 2018 Nim contributors
|
|
#
|
|
# See the file "copying.txt", included in this
|
|
# distribution, for details about the copyright.
|
|
#
|
|
## Warning: this test performs local networking.
|
|
## Test with:
|
|
## ./bin/nim c -d:ssl -p:. --threads:on -r tests/stdlib/thttpclient_ssl.nim
|
|
|
|
when not defined(windows):
|
|
# Disabled on Windows due to old OpenSSL version
|
|
|
|
import
|
|
httpclient,
|
|
net,
|
|
openssl,
|
|
os,
|
|
strutils,
|
|
threadpool,
|
|
times,
|
|
unittest
|
|
|
|
# bogus self-signed certificate
|
|
const
|
|
certFile = "tests/stdlib/thttpclient_ssl_cert.pem"
|
|
keyFile = "tests/stdlib/thttpclient_ssl_key.pem"
|
|
|
|
proc log(msg: string) =
|
|
when defined(ssldebug):
|
|
echo " [" & $epochTime() & "] " & msg
|
|
# FIXME
|
|
echo " [" & $epochTime() & "] " & msg
|
|
discard
|
|
|
|
proc runServer(port: Port): bool {.thread.} =
|
|
## Run a trivial HTTPS server in a {.thread.}
|
|
## Exit after serving one request
|
|
|
|
var socket = newSocket()
|
|
socket.setSockOpt(OptReusePort, true)
|
|
socket.bindAddr(port)
|
|
|
|
var ctx = newContext(certFile=certFile, keyFile=keyFile)
|
|
|
|
## Handle one connection
|
|
socket.listen()
|
|
|
|
var client: Socket
|
|
var address = ""
|
|
|
|
log "server: ready"
|
|
socket.acceptAddr(client, address)
|
|
log "server: incoming connection"
|
|
|
|
var ssl: SslPtr = SSL_new(ctx.context)
|
|
discard SSL_set_fd(ssl, client.getFd())
|
|
log "server: accepting connection"
|
|
if SSL_accept(ssl) <= 0:
|
|
ERR_print_errors_fp(stderr)
|
|
else:
|
|
const reply = "HTTP/1.0 200 OK\r\nServer: test\r\nContent-type: text/html\r\nContent-Length: 0\r\n\r\n"
|
|
log "server: sending reply"
|
|
discard SSL_write(ssl, reply.cstring, reply.len)
|
|
|
|
log "server: receiving a line"
|
|
let line = client.recvLine()
|
|
log "server: received $# bytes" % $line.len
|
|
log "closing"
|
|
SSL_free(ssl)
|
|
close(client)
|
|
close(socket)
|
|
log "server: exited"
|
|
|
|
|
|
suite "SSL self signed certificate check":
|
|
|
|
test "TCP socket":
|
|
const port = 12347.Port
|
|
let t = spawn runServer(port)
|
|
sleep(100)
|
|
var sock = newSocket()
|
|
var ctx = newContext()
|
|
ctx.wrapSocket(sock)
|
|
try:
|
|
log "client: connect"
|
|
sock.connect("127.0.0.1", port)
|
|
fail()
|
|
except:
|
|
let msg = getCurrentExceptionMsg()
|
|
check(msg.contains("certificate verify failed"))
|
|
|
|
test "HttpClient default: no check":
|
|
const port = 12345.Port
|
|
let t = spawn runServer(port)
|
|
sleep(100)
|
|
|
|
var client = newHttpClient()
|
|
try:
|
|
log "client: connect"
|
|
discard client.getContent("https://127.0.0.1:12345")
|
|
except:
|
|
let msg = getCurrentExceptionMsg()
|
|
log "client: unexpected exception: " & msg
|
|
fail()
|
|
|
|
test "HttpClient with CVerifyPeer":
|
|
const port = 12346.Port
|
|
let t = spawn runServer(port)
|
|
sleep(100)
|
|
|
|
var client = newHttpClient(sslContext=newContext(verifyMode=CVerifyPeer))
|
|
try:
|
|
log "client: connect"
|
|
discard client.getContent("https://127.0.0.1:12346")
|
|
log "getContent should have raised an exception"
|
|
fail()
|
|
except:
|
|
let msg = getCurrentExceptionMsg()
|
|
log "client: exception: " & msg
|
|
# SSL_shutdown:shutdown while in init
|
|
if not (msg.contains("alert number 48") or
|
|
msg.contains("certificate verify failed")):
|
|
echo "CVerifyPeer exception: " & msg
|
|
check(false)
|