net/win32-ssl: repairs for CS
This commit is contained in:
parent
350ecf3d49
commit
d0fab4027b
|
@ -247,7 +247,9 @@
|
||||||
;; Helpers to manage the clunky SecBuffer API
|
;; Helpers to manage the clunky SecBuffer API
|
||||||
|
|
||||||
(define (make-SecBuffers n)
|
(define (make-SecBuffers n)
|
||||||
(cast (malloc n _SecBuffer 'atomic-interior) _pointer _SecBuffer-pointer))
|
(define p (malloc n _SecBuffer 'atomic-interior))
|
||||||
|
(cpointer-push-tag! p SecBuffer-tag)
|
||||||
|
p)
|
||||||
|
|
||||||
(define (make-SecBuffers! sbs . vals)
|
(define (make-SecBuffers! sbs . vals)
|
||||||
(define n
|
(define n
|
||||||
|
@ -376,7 +378,8 @@
|
||||||
(log-win32-ssl-debug "init context: done")
|
(log-win32-ssl-debug "init context: done")
|
||||||
(values ctx
|
(values ctx
|
||||||
(let ([n (get-leftover-bytes)])
|
(let ([n (get-leftover-bytes)])
|
||||||
(pointer->bytes buffer n)))]
|
(pointer->bytes buffer n))
|
||||||
|
buffer)]
|
||||||
[(or (= r SEC_I_CONTINUE_NEEDED)
|
[(or (= r SEC_I_CONTINUE_NEEDED)
|
||||||
(= r SEC_E_INCOMPLETE_MESSAGE))
|
(= r SEC_E_INCOMPLETE_MESSAGE))
|
||||||
;; Pull more data from the server
|
;; Pull more data from the server
|
||||||
|
@ -406,19 +409,22 @@
|
||||||
[else (network-error 'create-context
|
[else (network-error 'create-context
|
||||||
"unexpected result: ~x" r)])))))
|
"unexpected result: ~x" r)])))))
|
||||||
|
|
||||||
(define (decrypt ctx in-pre-r in-post-w out-sb)
|
(define (decrypt ctx in-pre-r in-post-w out-sb msg-size)
|
||||||
;; Read encrypted byte from `in-pre-r', write decrypted bytes to
|
;; Read encrypted byte from `in-pre-r', write decrypted bytes to
|
||||||
;; `in-port-w'.
|
;; `in-port-w'.
|
||||||
;; Loop to try to get a big enough chunk from the input to be able
|
;; Loop to try to get a big enough chunk from the input to be able
|
||||||
;; to decrypt it.
|
;; to decrypt it.
|
||||||
(let loop ([size 4096] [prev-n 0])
|
(let loop ([size 4096] [prev-n 0])
|
||||||
(define buffer (make-bytes size))
|
(define buffer (make-bytes size))
|
||||||
(define n (peek-bytes-avail!* buffer 0 #f in-pre-r))
|
(define n (peek-bytes! buffer 0 in-pre-r 0 (min (bytes-length buffer)
|
||||||
|
(pipe-content-length in-pre-r))))
|
||||||
|
(define immobile-buffer (malloc (add1 n) 'atomic-interior))
|
||||||
|
(memcpy immobile-buffer buffer n)
|
||||||
(define r (DecryptMessage (ctx->handle ctx)
|
(define r (DecryptMessage (ctx->handle ctx)
|
||||||
(make-SecBuffers! out-sb
|
(make-SecBuffers! out-sb
|
||||||
n
|
n
|
||||||
SECBUFFER_DATA
|
SECBUFFER_DATA
|
||||||
buffer
|
immobile-buffer
|
||||||
0
|
0
|
||||||
SECBUFFER_EMPTY
|
SECBUFFER_EMPTY
|
||||||
#f
|
#f
|
||||||
|
@ -446,7 +452,7 @@
|
||||||
(write-bytes (pointer->bytes (SecBuffer-pvBuffer sb)
|
(write-bytes (pointer->bytes (SecBuffer-pvBuffer sb)
|
||||||
(SecBuffer-cbBuffer sb))
|
(SecBuffer-cbBuffer sb))
|
||||||
in-post-w)
|
in-post-w)
|
||||||
(define remain (or (for/or ([i (in-range 1 4)])
|
(define remain (or (for/or ([i (in-range 0 4)])
|
||||||
(define sb (ptr-ref out-sb _SecBuffer i))
|
(define sb (ptr-ref out-sb _SecBuffer i))
|
||||||
(and (= SECBUFFER_EXTRA (SecBuffer-BufferType sb))
|
(and (= SECBUFFER_EXTRA (SecBuffer-BufferType sb))
|
||||||
(SecBuffer-cbBuffer sb)))
|
(SecBuffer-cbBuffer sb)))
|
||||||
|
@ -456,6 +462,7 @@
|
||||||
(SecBuffer-cbBuffer sb)
|
(SecBuffer-cbBuffer sb)
|
||||||
remain)
|
remain)
|
||||||
(read-bytes! buffer in-pre-r 0 (- n remain))
|
(read-bytes! buffer in-pre-r 0 (- n remain))
|
||||||
|
(void/reference-sink immobile-buffer)
|
||||||
(unless (zero? remain)
|
(unless (zero? remain)
|
||||||
(loop size 0))]
|
(loop size 0))]
|
||||||
[(= r SEC_E_INCOMPLETE_MESSAGE)
|
[(= r SEC_E_INCOMPLETE_MESSAGE)
|
||||||
|
@ -470,16 +477,16 @@
|
||||||
[else
|
[else
|
||||||
(network-error 'decrypt "unexpected result: ~x" r)])))
|
(network-error 'decrypt "unexpected result: ~x" r)])))
|
||||||
|
|
||||||
(define (encrypt ctx bstr start end out-sb sizes buffer)
|
(define (encrypt ctx bstr start end out-sb sizes buffer buffer-len)
|
||||||
;; Encrypt bytes [start, end) from bstr.
|
;; Encrypt bytes [start, end) from bstr.
|
||||||
;; If we have too much to encrypt at once, we'll encrypt
|
;; If we have too much to encrypt at once, we'll encrypt
|
||||||
;; halves separately:
|
;; halves separately:
|
||||||
(define (divide-and-conquer)
|
(define (divide-and-conquer)
|
||||||
(define mid (quotient (+ start end) 2))
|
(define mid (quotient (+ start end) 2))
|
||||||
(bytes-append (encrypt ctx bstr start mid out-sb sizes buffer)
|
(bytes-append (encrypt ctx bstr start mid out-sb sizes buffer buffer-len)
|
||||||
(encrypt ctx bstr mid end out-sb sizes buffer)))
|
(encrypt ctx bstr mid end out-sb sizes buffer buffer-len)))
|
||||||
(cond
|
(cond
|
||||||
[((- end start) . > . (bytes-length buffer))
|
[((- end start) . > . buffer-len)
|
||||||
;; Too much right from the start:
|
;; Too much right from the start:
|
||||||
(divide-and-conquer)]
|
(divide-and-conquer)]
|
||||||
[else
|
[else
|
||||||
|
@ -513,7 +520,9 @@
|
||||||
(define len (+ (SecBuffer-cbBuffer (ptr-ref out-sb _SecBuffer 0))
|
(define len (+ (SecBuffer-cbBuffer (ptr-ref out-sb _SecBuffer 0))
|
||||||
(SecBuffer-cbBuffer (ptr-ref out-sb _SecBuffer 1))
|
(SecBuffer-cbBuffer (ptr-ref out-sb _SecBuffer 1))
|
||||||
(SecBuffer-cbBuffer (ptr-ref out-sb _SecBuffer 2))))
|
(SecBuffer-cbBuffer (ptr-ref out-sb _SecBuffer 2))))
|
||||||
(subbytes buffer 0 len)]
|
(define result (make-bytes len))
|
||||||
|
(memcpy result buffer len)
|
||||||
|
result]
|
||||||
[(= r SEC_E_BUFFER_TOO_SMALL)
|
[(= r SEC_E_BUFFER_TOO_SMALL)
|
||||||
;; The encrypted bytes don't fit in the unencrypted space?
|
;; The encrypted bytes don't fit in the unencrypted space?
|
||||||
(divide-and-conquer)]
|
(divide-and-conquer)]
|
||||||
|
@ -529,7 +538,7 @@
|
||||||
(define in-sb (make-SecBuffers 2))
|
(define in-sb (make-SecBuffers 2))
|
||||||
|
|
||||||
;; Allocate the encoding/decoding context:
|
;; Allocate the encoding/decoding context:
|
||||||
(define-values (ctx init-bytes) (create-context protocol hostname i o out-sb in-sb))
|
(define-values (ctx init-bytes tok-buffer) (create-context protocol hostname i o out-sb in-sb))
|
||||||
|
|
||||||
;; Get some sizes that we need for encoding:
|
;; Get some sizes that we need for encoding:
|
||||||
(define sizes (make-SecPkgContext_StreamSizes 0 0 0 0 0))
|
(define sizes (make-SecPkgContext_StreamSizes 0 0 0 0 0))
|
||||||
|
@ -539,16 +548,19 @@
|
||||||
(define msize (SecPkgContext_StreamSizes-cbMaximumMessage sizes))
|
(define msize (SecPkgContext_StreamSizes-cbMaximumMessage sizes))
|
||||||
(define hsize (SecPkgContext_StreamSizes-cbHeader sizes))
|
(define hsize (SecPkgContext_StreamSizes-cbHeader sizes))
|
||||||
(define tsize (SecPkgContext_StreamSizes-cbTrailer sizes))
|
(define tsize (SecPkgContext_StreamSizes-cbTrailer sizes))
|
||||||
|
(define msg-size (+ msize hsize tsize))
|
||||||
|
|
||||||
;; Some pipes to manage the decoding stream:
|
;; Some pipes to manage the decoding stream:
|
||||||
(define-values (in-pre-r in-pre-w) (make-pipe))
|
(define-values (in-pre-r in-pre-w) (make-pipe))
|
||||||
(define-values (in-post-r in-post-w) (make-pipe))
|
(define-values (in-post-r in-post-w) (make-pipe))
|
||||||
|
|
||||||
(write-bytes init-bytes in-pre-w)
|
(write-bytes init-bytes in-pre-w)
|
||||||
(decrypt ctx in-pre-r in-post-w out-sb)
|
(decrypt ctx in-pre-r in-post-w out-sb msg-size)
|
||||||
|
|
||||||
;; More working space:
|
;; More working space:
|
||||||
(define buffer (make-bytes (max 8000 (+ msize hsize tsize))))
|
(define buffer (make-bytes (max 8000 (+ msize hsize tsize))))
|
||||||
|
(define out-buffer-len (bytes-length buffer))
|
||||||
|
(define out-buffer (malloc (add1 out-buffer-len) 'atomic-interior))
|
||||||
|
|
||||||
;; Port lock and state:
|
;; Port lock and state:
|
||||||
(define lock (make-semaphore 1))
|
(define lock (make-semaphore 1))
|
||||||
|
@ -563,7 +575,10 @@
|
||||||
(close-output-port o)
|
(close-output-port o)
|
||||||
(let ([v ctx])
|
(let ([v ctx])
|
||||||
(set! ctx #f)
|
(set! ctx #f)
|
||||||
(when v (free-ctx v)))))
|
(when v (free-ctx v)))
|
||||||
|
(void/reference-sink tok-buffer)
|
||||||
|
(void/reference-sink in-sb)
|
||||||
|
(void/reference-sink out-sb)))
|
||||||
|
|
||||||
;; Callbacks used below (written here so that they're allocated once):
|
;; Callbacks used below (written here so that they're allocated once):
|
||||||
(define (lock-unavailable/read) (wrap-evt lock (lambda () 0)))
|
(define (lock-unavailable/read) (wrap-evt lock (lambda () 0)))
|
||||||
|
@ -585,16 +600,15 @@
|
||||||
n]
|
n]
|
||||||
[(zero? n)
|
[(zero? n)
|
||||||
;; Nothing decrypted, no new input, so wait for input:
|
;; Nothing decrypted, no new input, so wait for input:
|
||||||
(log-win32-ssl-debug "blocked")
|
|
||||||
(wrap-evt i (lambda (v) 0))]
|
(wrap-evt i (lambda (v) 0))]
|
||||||
[else
|
[else
|
||||||
(log-win32-ssl-debug "underlying receive: ~a" n)
|
(log-win32-ssl-debug "underlying receive: ~a" n)
|
||||||
;; Get some fresh bytes, so try decoding now:
|
;; Got some fresh bytes, so try decoding now:
|
||||||
(write-bytes buffer in-pre-w 0 n)
|
(write-bytes buffer in-pre-w 0 n)
|
||||||
(decrypt ctx in-pre-r in-post-w out-sb)
|
(decrypt ctx in-pre-r in-post-w out-sb msg-size)
|
||||||
(loop)])]
|
(loop)])]
|
||||||
[else n])))
|
[else n])))
|
||||||
|
|
||||||
;; The new input port:
|
;; The new input port:
|
||||||
(define in (make-input-port/read-to-peek
|
(define in (make-input-port/read-to-peek
|
||||||
(format "SSL ~a" (object-name i))
|
(format "SSL ~a" (object-name i))
|
||||||
|
@ -627,7 +641,7 @@
|
||||||
0]
|
0]
|
||||||
[(not leftover-bytes)
|
[(not leftover-bytes)
|
||||||
;; Nothing in the output buffer, so we can encrypt more
|
;; Nothing in the output buffer, so we can encrypt more
|
||||||
(define encrypted-bstr (encrypt ctx bstr start end out-sb sizes buffer))
|
(define encrypted-bstr (encrypt ctx bstr start end out-sb sizes out-buffer out-buffer-len))
|
||||||
(define n (write-bytes-avail* encrypted-bstr o))
|
(define n (write-bytes-avail* encrypted-bstr o))
|
||||||
(cond
|
(cond
|
||||||
[(zero? n)
|
[(zero? n)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user