ruby-tls 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,129 +1,130 @@
1
- /*****************************************************************************
2
-
3
- $Id$
4
-
5
- File: ssl.h
6
- Date: 30Apr06
7
-
8
- Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
9
- Gmail: blackhedd
10
-
11
- This program is free software; you can redistribute it and/or modify
12
- it under the terms of either: 1) the GNU General Public License
13
- as published by the Free Software Foundation; either version 2 of the
14
- License, or (at your option) any later version; or 2) Ruby's License.
15
-
16
- See the file COPYING for complete licensing information.
17
-
18
- *****************************************************************************/
19
-
20
-
21
- #ifndef __SslBox__H_
22
- #define __SslBox__H_
23
-
24
- #include <iostream>
25
- #include <string>
26
-
27
- #include <openssl/ssl.h>
28
- #include <openssl/err.h>
29
-
30
- #include <assert.h>
31
-
32
- #include "page.h"
33
-
34
- using namespace std;
35
-
36
-
37
- /******************
38
- class SslContext_t
39
- ******************/
40
-
41
- class SslContext_t
42
- {
43
- public:
44
- SslContext_t (bool is_server, const string &privkeyfile, const string &certchainfile);
45
- virtual ~SslContext_t();
46
-
47
- private:
48
- bool bIsServer;
49
- SSL_CTX *pCtx;
50
-
51
- EVP_PKEY *PrivateKey;
52
- X509 *Certificate;
53
-
54
- friend class SslBox_t;
55
- };
56
-
57
-
58
-
59
-
60
- typedef struct tls_state_s tls_state_t;
61
-
62
-
63
-
64
- /**************
65
- class SslBox_t
66
- **************/
67
-
68
- class SslBox_t
69
- {
70
- public:
71
- SslBox_t (tls_state_t *tls_state, bool is_server, const string &privkeyfile, const string &certchainfile, bool verify_peer);
72
- virtual ~SslBox_t();
73
-
74
- int PutPlaintext (const char*, int);
75
- int GetPlaintext (char*, int);
76
-
77
- bool PutCiphertext (const char*, int);
78
- bool CanGetCiphertext();
79
- int GetCiphertext (char*, int);
80
- bool IsHandshakeCompleted() { return bHandshakeCompleted; }
81
-
82
- X509 *GetPeerCert();
83
-
84
- void Shutdown();
85
-
86
- protected:
87
- SslContext_t *Context;
88
-
89
- bool bIsServer;
90
- bool bHandshakeCompleted;
91
- bool bVerifyPeer;
92
- SSL *pSSL;
93
- BIO *pbioRead;
94
- BIO *pbioWrite;
95
-
96
- PageList OutboundQ;
97
- };
98
-
99
-
100
- typedef void (*ssl_close_cb)(const tls_state_t*);
101
- typedef int (*ssl_verify_cb)(const tls_state_t*, const char *cert);
102
- typedef void (*ssl_dispatch_cb)(const tls_state_t*, const char *buffer, int size);
103
- typedef void (*ssl_transmit_cb)(const tls_state_t*, const char *buffer, int size);
104
- typedef void (*ssl_handshake_cb)(const tls_state_t*);
105
-
106
- struct tls_state_s {
107
- int handshake_signaled;
108
-
109
- ssl_close_cb close_cb;
110
- ssl_verify_cb verify_cb;
111
- ssl_dispatch_cb dispatch_cb;
112
- ssl_transmit_cb transmit_cb;
113
- ssl_handshake_cb handshake_cb;
114
-
115
- SslBox_t* SslBox;
116
- };
117
-
118
-
119
- extern "C" int ssl_verify_wrapper(int preverify_ok, X509_STORE_CTX *ctx);
120
-
121
- extern "C" void start_tls(tls_state_t *tls_state, bool bIsServer, const char *PrivateKeyFilename, const char *CertChainFilename, bool bSslVerifyPeer);
122
- extern "C" void decrypt_data(tls_state_t *tls_state, const char *buffer, int size);
123
- extern "C" void encrypt_data(tls_state_t *tls_state, const char *data, int length);
124
- extern "C" X509 *get_peer_cert(tls_state_t *tls_state);
125
-
126
- extern "C" void init_rubytls();
127
-
128
-
129
- #endif // __SslBox__H_
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: ssl.h
6
+ Date: 30Apr06
7
+
8
+ Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
9
+ Gmail: blackhedd
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of either: 1) the GNU General Public License
13
+ as published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version; or 2) Ruby's License.
15
+
16
+ See the file COPYING for complete licensing information.
17
+
18
+ *****************************************************************************/
19
+
20
+
21
+ #ifndef __SslBox__H_
22
+ #define __SslBox__H_
23
+
24
+ #include <iostream>
25
+ #include <string>
26
+
27
+ #include <openssl/ssl.h>
28
+ #include <openssl/err.h>
29
+
30
+ #include <assert.h>
31
+
32
+ #include "page.h"
33
+
34
+ using namespace std;
35
+
36
+
37
+ /******************
38
+ class SslContext_t
39
+ ******************/
40
+
41
+ class SslContext_t
42
+ {
43
+ public:
44
+ SslContext_t (bool is_server, const string &privkeyfile, const string &certchainfile);
45
+ virtual ~SslContext_t();
46
+
47
+ private:
48
+ bool bIsServer;
49
+ SSL_CTX *pCtx;
50
+
51
+ EVP_PKEY *PrivateKey;
52
+ X509 *Certificate;
53
+
54
+ friend class SslBox_t;
55
+ };
56
+
57
+
58
+
59
+
60
+ typedef struct tls_state_s tls_state_t;
61
+
62
+
63
+
64
+ /**************
65
+ class SslBox_t
66
+ **************/
67
+
68
+ class SslBox_t
69
+ {
70
+ public:
71
+ SslBox_t (tls_state_t *tls_state, bool is_server, const string &privkeyfile, const string &certchainfile, bool verify_peer);
72
+ virtual ~SslBox_t();
73
+
74
+ int PutPlaintext (const char*, int);
75
+ int GetPlaintext (char*, int);
76
+
77
+ bool PutCiphertext (const char*, int);
78
+ bool CanGetCiphertext();
79
+ int GetCiphertext (char*, int);
80
+ bool IsHandshakeCompleted() { return bHandshakeCompleted; }
81
+
82
+ X509 *GetPeerCert();
83
+
84
+ void Shutdown();
85
+
86
+ protected:
87
+ SslContext_t *Context;
88
+
89
+ bool bIsServer;
90
+ bool bHandshakeCompleted;
91
+ bool bVerifyPeer;
92
+ SSL *pSSL;
93
+ BIO *pbioRead;
94
+ BIO *pbioWrite;
95
+
96
+ PageList OutboundQ;
97
+ };
98
+
99
+
100
+ typedef void (*ssl_close_cb)(const tls_state_t*);
101
+ typedef int (*ssl_verify_cb)(const tls_state_t*, const char *cert);
102
+ typedef void (*ssl_dispatch_cb)(const tls_state_t*, const char *buffer, int size);
103
+ typedef void (*ssl_transmit_cb)(const tls_state_t*, const char *buffer, int size);
104
+ typedef void (*ssl_handshake_cb)(const tls_state_t*);
105
+
106
+ struct tls_state_s {
107
+ int handshake_signaled;
108
+
109
+ ssl_close_cb close_cb;
110
+ ssl_verify_cb verify_cb;
111
+ ssl_dispatch_cb dispatch_cb;
112
+ ssl_transmit_cb transmit_cb;
113
+ ssl_handshake_cb handshake_cb;
114
+
115
+ SslBox_t* SslBox;
116
+ };
117
+
118
+
119
+ extern "C" int ssl_verify_wrapper(int preverify_ok, X509_STORE_CTX *ctx);
120
+
121
+ extern "C" void start_tls(tls_state_t *tls_state, bool bIsServer, const char *PrivateKeyFilename, const char *CertChainFilename, bool bSslVerifyPeer);
122
+ extern "C" void cleanup(tls_state_t *tls_state);
123
+ extern "C" void decrypt_data(tls_state_t *tls_state, const char *buffer, int size);
124
+ extern "C" void encrypt_data(tls_state_t *tls_state, const char *data, int length);
125
+ extern "C" X509 *get_peer_cert(tls_state_t *tls_state);
126
+
127
+ extern "C" void init_rubytls();
128
+
129
+
130
+ #endif // __SslBox__H_
@@ -1,7 +1,7 @@
1
- require "ffi" # Bindings to C libraries
2
-
3
- require "ruby-tls/ext" # Loads the ext using FFI
4
- require "ruby-tls/connection" # The ruby abstraction
5
-
6
- module RubyTls
7
- end
1
+ require "ffi" # Bindings to C libraries
2
+
3
+ require "ruby-tls/ext" # Loads the ext using FFI
4
+ require "ruby-tls/connection" # The ruby abstraction
5
+
6
+ module RubyTls
7
+ end
@@ -1,121 +1,124 @@
1
-
2
- module RubyTls
3
- class Connection
4
- CALLBACKS = [:close_cb, :verify_cb, :dispatch_cb, :transmit_cb, :handshake_cb]
5
-
6
- #
7
- # Initializes the State instance.
8
- #
9
- def initialize(callback_obj = nil)
10
- @state = ::RubyTls::State.new
11
- @callbacks = {} # so GC doesn't clean them up on java
12
- @started = false
13
-
14
- if not callback_obj.nil?
15
- CALLBACKS.each do |callback|
16
- self.__send__(callback, &callback_obj.method(callback)) if callback_obj.respond_to? callback
17
- end
18
- end
19
-
20
- yield self if block_given?
21
- end
22
-
23
- def close_cb(&block)
24
- cb = Callback.new(@callbacks, &block)
25
- @callbacks[:close_cb] = cb
26
- @state[:close_cb] = cb
27
- end
28
-
29
- def verify_cb
30
- cb = ::FFI::Function.new(:int, [::RubyTls::State.ptr, :string]) do |state, cert|
31
- begin
32
- yield(cert) == true ? 1 : 0
33
- rescue
34
- # TODO:: Provide some debugging output
35
- 0
36
- end
37
- end
38
- @callbacks[:verify_cb] = cb
39
- @state[:verify_cb] = cb
40
- end
41
-
42
- def dispatch_cb(&block)
43
- cb = DataCallback.new(@callbacks, &block)
44
- @callbacks[:dispatch_cb] = cb
45
- @state[:dispatch_cb] = cb
46
- end
47
-
48
- def transmit_cb(&block)
49
- cb = DataCallback.new(@callbacks, &block)
50
- @callbacks[:transmit_cb] = cb
51
- @state[:transmit_cb] = cb
52
- end
53
-
54
- def handshake_cb(&block)
55
- cb = Callback.new(@callbacks, &block)
56
- @callbacks[:handshake_cb] = cb
57
- @state[:handshake_cb] = cb
58
- end
59
-
60
-
61
- def start(args = {})
62
- return if @started
63
-
64
- server, priv_key, cert_chain, verify_peer = args.values_at(:server, :private_key_file, :cert_chain_file, :verify_peer)
65
- [priv_key, cert_chain].each do |file|
66
- next if file.nil? or file.empty?
67
- raise FileNotFoundException,
68
- "Could not find #{file} to start tls" unless File.exists? file
69
- end
70
-
71
- @started = true
72
- ::RubyTls.start_tls(@state, server || false, priv_key || '', cert_chain || '', verify_peer || !!@callbacks[:verify_cb])
73
- end
74
-
75
- def encrypt(data)
76
- return unless @started
77
- ::RubyTls.encrypt_data(@state, data, data.length)
78
- end
79
-
80
- def decrypt(data)
81
- return unless @started
82
- ::RubyTls.decrypt_data(@state, data, data.length)
83
- end
84
-
85
-
86
- protected
87
-
88
-
89
- class Callback < ::FFI::Function
90
- #
91
- # Creates a new Parser callback.
92
- #
93
- def self.new(callbacks)
94
- super(:void, [::RubyTls::State.ptr]) do |state|
95
- begin
96
- yield
97
- rescue => e
98
- # shutdown the connection on error
99
- # TODO:: Provide some debugging output
100
- callbacks[:close_cb].call state
101
- end
102
- end
103
- end
104
- end
105
-
106
- class DataCallback < ::FFI::Function
107
- def self.new(callbacks)
108
- super(:void, [::RubyTls::State.ptr, :pointer, :int]) do |state, buffer, length|
109
- begin
110
- data = buffer.get_bytes(0, length)
111
- yield(data)
112
- rescue => e
113
- # shutdown the connection on error
114
- # TODO:: Provide some debugging output
115
- callbacks[:close_cb].call state
116
- end
117
- end
118
- end
119
- end
120
- end
121
- end
1
+
2
+ module RubyTls
3
+ class Connection
4
+ CALLBACKS = [:close_cb, :verify_cb, :dispatch_cb, :transmit_cb, :handshake_cb].freeze
5
+ Callbacks = Struct.new(*CALLBACKS)
6
+
7
+ #
8
+ # Initializes the State instance.
9
+ #
10
+ def initialize(callback_obj = nil)
11
+ @state = ::RubyTls::State.new
12
+ @callbacks = Callbacks.new # so GC doesn't clean them up on java
13
+ @started = false
14
+
15
+ # Attach callbacks if there is an object passed in to handle the callbacks
16
+ if not callback_obj.nil?
17
+ CALLBACKS.each do |callback|
18
+ self.__send__(callback, &callback_obj.method(callback)) if callback_obj.respond_to? callback
19
+ end
20
+ end
21
+
22
+ yield self if block_given?
23
+ end
24
+
25
+ def close_cb(&block)
26
+ cb = Callback.new(@callbacks, &block)
27
+ @callbacks[:close_cb] = cb
28
+ @state[:close_cb] = cb
29
+ end
30
+
31
+ def verify_cb
32
+ cb = ::FFI::Function.new(:int, [::RubyTls::State.ptr, :string]) do |state, cert|
33
+ begin
34
+ yield(cert) == true ? 1 : 0
35
+ rescue
36
+ # TODO:: Provide some debugging output
37
+ 0
38
+ end
39
+ end
40
+ @callbacks[:verify_cb] = cb
41
+ @state[:verify_cb] = cb
42
+ end
43
+
44
+ def dispatch_cb(&block)
45
+ cb = DataCallback.new(@callbacks, &block)
46
+ @callbacks[:dispatch_cb] = cb
47
+ @state[:dispatch_cb] = cb
48
+ end
49
+
50
+ def transmit_cb(&block)
51
+ cb = DataCallback.new(@callbacks, &block)
52
+ @callbacks[:transmit_cb] = cb
53
+ @state[:transmit_cb] = cb
54
+ end
55
+
56
+ def handshake_cb(&block)
57
+ cb = Callback.new(@callbacks, &block)
58
+ @callbacks[:handshake_cb] = cb
59
+ @state[:handshake_cb] = cb
60
+ end
61
+
62
+
63
+ def start(args = {})
64
+ return if @started
65
+
66
+ server, priv_key, cert_chain, verify_peer = args.values_at(:server, :private_key_file, :cert_chain_file, :verify_peer)
67
+ [priv_key, cert_chain].each do |file|
68
+ next if file.nil? or file.empty?
69
+ raise FileNotFoundException,
70
+ "Could not find #{file} to start tls" unless File.exists? file
71
+ end
72
+ @started = true
73
+ ::RubyTls.start_tls(@state, server || false, priv_key || '', cert_chain || '', verify_peer || !!@callbacks[:verify_cb])
74
+ end
75
+
76
+ def encrypt(data)
77
+ ::RubyTls.encrypt_data(@state, data, data.length)
78
+ end
79
+
80
+ def decrypt(data)
81
+ ::RubyTls.decrypt_data(@state, data, data.length)
82
+ end
83
+
84
+ def cleanup
85
+ ::RubyTls.cleanup(@state)
86
+ end
87
+
88
+
89
+ protected
90
+
91
+
92
+ class Callback < ::FFI::Function
93
+ #
94
+ # Creates a new Parser callback.
95
+ #
96
+ def self.new(callbacks)
97
+ super(:void, [::RubyTls::State.ptr]) do |state|
98
+ begin
99
+ yield
100
+ rescue => e
101
+ # shutdown the connection on error
102
+ # TODO:: Provide some debugging output
103
+ callbacks[:close_cb].call state
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ class DataCallback < ::FFI::Function
110
+ def self.new(callbacks)
111
+ super(:void, [::RubyTls::State.ptr, :pointer, :int]) do |state, buffer, length|
112
+ begin
113
+ data = buffer.get_bytes(0, length)
114
+ yield(data)
115
+ rescue => e
116
+ # shutdown the connection on error
117
+ # TODO:: Provide some debugging output
118
+ callbacks[:close_cb].call state
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end