add ssl-seal-context!
Unsealed contexts are not safe to share, because one user may change it in a way that ruins the security of another.
This commit is contained in:
parent
98633665b3
commit
c632a84a95
|
@ -38,6 +38,7 @@
|
||||||
ssl-load-private-key!
|
ssl-load-private-key!
|
||||||
ssl-load-verify-root-certificates!
|
ssl-load-verify-root-certificates!
|
||||||
ssl-load-suggested-certificate-authorities!
|
ssl-load-suggested-certificate-authorities!
|
||||||
|
ssl-seal-context!
|
||||||
|
|
||||||
ssl-set-verify!
|
ssl-set-verify!
|
||||||
ssl-try-verify!
|
ssl-try-verify!
|
||||||
|
@ -301,7 +302,7 @@
|
||||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Structs
|
;; Structs
|
||||||
|
|
||||||
(define-struct ssl-context (ctx [verify-hostname? #:mutable]))
|
(define-struct ssl-context (ctx [verify-hostname? #:mutable] [sealed? #:mutable]))
|
||||||
(define-struct (ssl-client-context ssl-context) ())
|
(define-struct (ssl-client-context ssl-context) ())
|
||||||
(define-struct (ssl-server-context ssl-context) ())
|
(define-struct (ssl-server-context ssl-context) ())
|
||||||
|
|
||||||
|
@ -392,7 +393,7 @@
|
||||||
(SSL_CTX_set_mode ctx (bitwise-ior SSL_MODE_ENABLE_PARTIAL_WRITE
|
(SSL_CTX_set_mode ctx (bitwise-ior SSL_MODE_ENABLE_PARTIAL_WRITE
|
||||||
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))
|
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))
|
||||||
(register-finalizer ctx (lambda (v) (SSL_CTX_free v)))
|
(register-finalizer ctx (lambda (v) (SSL_CTX_free v)))
|
||||||
((if client? make-ssl-client-context make-ssl-server-context) ctx #f)))))
|
((if client? make-ssl-client-context make-ssl-server-context) ctx #f #f)))))
|
||||||
|
|
||||||
(define (ssl-make-client-context [protocol-symbol default-encrypt])
|
(define (ssl-make-client-context [protocol-symbol default-encrypt])
|
||||||
(make-context 'ssl-make-client-context protocol-symbol "" #t))
|
(make-context 'ssl-make-client-context protocol-symbol "" #t))
|
||||||
|
@ -400,19 +401,21 @@
|
||||||
(define (ssl-make-server-context [protocol-symbol default-encrypt])
|
(define (ssl-make-server-context [protocol-symbol default-encrypt])
|
||||||
(make-context 'ssl-make-server-context protocol-symbol "" #f))
|
(make-context 'ssl-make-server-context protocol-symbol "" #f))
|
||||||
|
|
||||||
(define (get-context who context-or-encrypt-method client?)
|
(define (get-context who context-or-encrypt-method client?
|
||||||
|
#:need-unsealed? [need-unsealed? #f])
|
||||||
(if (ssl-context? context-or-encrypt-method)
|
(if (ssl-context? context-or-encrypt-method)
|
||||||
(ssl-context-ctx context-or-encrypt-method)
|
(extract-ctx who need-unsealed? context-or-encrypt-method)
|
||||||
(let ([ctx (SSL_CTX_new (encrypt->method who "ssl-context? " context-or-encrypt-method client?))])
|
(let ([ctx (SSL_CTX_new (encrypt->method who "ssl-context? " context-or-encrypt-method client?))])
|
||||||
(SSL_CTX_set_mode ctx SSL_MODE_ENABLE_PARTIAL_WRITE)
|
(SSL_CTX_set_mode ctx SSL_MODE_ENABLE_PARTIAL_WRITE)
|
||||||
ctx)))
|
ctx)))
|
||||||
|
|
||||||
(define (get-context/listener who ssl-context-or-listener [fail? #t])
|
(define (get-context/listener who ssl-context-or-listener [fail? #t]
|
||||||
|
#:need-unsealed? [need-unsealed? #f])
|
||||||
(cond
|
(cond
|
||||||
[(ssl-context? ssl-context-or-listener)
|
[(ssl-context? ssl-context-or-listener)
|
||||||
(ssl-context-ctx ssl-context-or-listener)]
|
(extract-ctx who need-unsealed? ssl-context-or-listener)]
|
||||||
[(ssl-listener? ssl-context-or-listener)
|
[(ssl-listener? ssl-context-or-listener)
|
||||||
(ssl-context-ctx (ssl-listener-mzctx ssl-context-or-listener))]
|
(extract-ctx who need-unsealed? (ssl-listener-mzctx ssl-context-or-listener))]
|
||||||
[else
|
[else
|
||||||
(if fail?
|
(if fail?
|
||||||
(raise-argument-error who
|
(raise-argument-error who
|
||||||
|
@ -420,9 +423,22 @@
|
||||||
ssl-context-or-listener)
|
ssl-context-or-listener)
|
||||||
#f)]))
|
#f)]))
|
||||||
|
|
||||||
|
(define (extract-ctx who need-unsealed? mzctx)
|
||||||
|
(when (and need-unsealed? (ssl-context-sealed? mzctx))
|
||||||
|
(error who "context is sealed; no further changes are allowed"))
|
||||||
|
(ssl-context-ctx mzctx))
|
||||||
|
|
||||||
|
(define (ssl-seal-context! mzctx)
|
||||||
|
(unless (ssl-context? mzctx)
|
||||||
|
(raise-argument-error 'ssl-seal-context!
|
||||||
|
"(or/c ssl-client-context? ssl-server-context?)"
|
||||||
|
mzctx))
|
||||||
|
(set-ssl-context-sealed?! mzctx #t))
|
||||||
|
|
||||||
(define (ssl-load-... who load-it ssl-context-or-listener pathname)
|
(define (ssl-load-... who load-it ssl-context-or-listener pathname)
|
||||||
(let ([ctx (get-context/listener 'ssl-load-certificate-chain!
|
(let ([ctx (get-context/listener 'ssl-load-certificate-chain!
|
||||||
ssl-context-or-listener)])
|
ssl-context-or-listener
|
||||||
|
#:need-unsealed? #t)])
|
||||||
(unless (path-string? pathname)
|
(unless (path-string? pathname)
|
||||||
(raise-argument-error 'ssl-load-certificate-chain!
|
(raise-argument-error 'ssl-load-certificate-chain!
|
||||||
"path-string?"
|
"path-string?"
|
||||||
|
@ -475,6 +491,7 @@
|
||||||
(raise-argument-error 'ssl-set-verify-hostname!
|
(raise-argument-error 'ssl-set-verify-hostname!
|
||||||
"(or/c ssl-client-context? ssl-server-context?)"
|
"(or/c ssl-client-context? ssl-server-context?)"
|
||||||
ssl-context))
|
ssl-context))
|
||||||
|
(void (extract-ctx 'ssl-set-verify-hostname! #t ssl-context))
|
||||||
(set-ssl-context-verify-hostname?! ssl-context (and on? #t)))
|
(set-ssl-context-verify-hostname?! ssl-context (and on? #t)))
|
||||||
|
|
||||||
(define (ssl-try-verify! ssl-context-or-listener-or-port on?)
|
(define (ssl-try-verify! ssl-context-or-listener-or-port on?)
|
||||||
|
@ -492,7 +509,8 @@
|
||||||
(cond
|
(cond
|
||||||
[(get-context/listener who
|
[(get-context/listener who
|
||||||
ssl-context-or-listener-or-port
|
ssl-context-or-listener-or-port
|
||||||
#f)
|
#f
|
||||||
|
#:need-unsealed? #t)
|
||||||
=> (lambda (ctx)
|
=> (lambda (ctx)
|
||||||
;; required by openssl. This is more for when calling i2d_SSL_SESSION/d2i_SSL_SESSION
|
;; required by openssl. This is more for when calling i2d_SSL_SESSION/d2i_SSL_SESSION
|
||||||
;; for instance if we were saving sessions in a database etc... We aren't using that
|
;; for instance if we were saving sessions in a database etc... We aren't using that
|
||||||
|
|
|
@ -393,6 +393,15 @@ You can use the file @filepath{test.pem} of the @filepath{openssl}
|
||||||
collection for testing purposes where the peer identifies itself using
|
collection for testing purposes where the peer identifies itself using
|
||||||
@filepath{test.pem}.}
|
@filepath{test.pem}.}
|
||||||
|
|
||||||
|
@defproc[(ssl-seal-context! [context (or/c ssl-client-context? ssl-server-context?)])
|
||||||
|
void?]{
|
||||||
|
|
||||||
|
Seals @racket[context], preventing further modifications. After a
|
||||||
|
context is sealed, passing it to functions such as
|
||||||
|
@racket[ssl-set-verify!] and
|
||||||
|
@racket[ssl-load-verify-root-certificates!] results in an error.}
|
||||||
|
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
@section[#:tag "peer-verif"]{Peer Verification}
|
@section[#:tag "peer-verif"]{Peer Verification}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user