File: SecureChannel.h

package info (click to toggle)
storm-lang 0.7.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,028 kB
  • sloc: ansic: 261,471; cpp: 140,432; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (171 lines) | stat: -rw-r--r-- 4,489 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#pragma once

#ifdef WINDOWS

// Common includes for Windows.
#define SECURITY_WIN32
#include <Security.h>
#include <Schannel.h>

// Missing from time to time.
#ifndef SECBUFFER_ALERT
#define SECBUFFER_ALERT 17
#endif

#include "Data.h"
#include "WinCert.h"
#include "Core/Io/Buffer.h"

namespace ssl {

	class SChannelData;
	class ClientContext;
	class ServerContext;
	class CertificateKey;

	/**
	 * Various types we use on Windows.
	 */

	/**
	 * SSL credentials for SChannel.
	 */
	class SChannelContext : public SSLContext {
	public:
		virtual ~SChannelContext();

		// Acquired credentials.
		CredHandle credentials;

		// SSL Certificate to use, if any.
		RefPtr<WinSSLCert> certificate;

		// Create for a client context.
		static SChannelContext *createClient(ClientContext *context);

		// Create for a server context.
		static SChannelContext *createServer(ServerContext *context, CertificateKey *key);

		// Create a session for this context.
		virtual SSLSession *createSession();

	private:
		// Create.
		SChannelContext(CredHandle handle, bool isServer);

		// Server- or client context?
		bool isServer;
	};


	/**
	 * Data for a SSL session.
	 */
	class SChannelSession : public SSLSession {
	public:
		// Create.
		SChannelSession(SChannelContext *data);

		virtual ~SChannelSession();

		// Implementation of the generic interface.
		virtual Bool more(void *gcData);
		virtual void read(Buffer &to, void *gcData);
		virtual void peek(Buffer &to, void *gcData);
		virtual Nat write(const Buffer &from, Nat start, void *gcData);
		virtual Bool flush(void *gcData);
		virtual void close(void *gcData);

	protected:
		// Owning data, so we don't free it too early.
		SChannelContext *data;

		// Session (called a context here). Initialized when we first update the context.
		CtxtHandle context;

		// Maximum message size for encryption/decryption. Set when the session is established.
		Nat maxMessageSize;

		// Block size for the cipher. Optimal encoding if messages are a size modulo this size (seems to be 16 often)
		Nat blockSize;

		// Buffer sizes for headers and trailers.
		Nat headerSize;
		Nat trailerSize;

		// Initialize a session. Reads data from "input" (empty at first), and writes to
		// "output". The function clears the part of "input" that was consumed, and may leave parts
		// of it there. "output" is to be sent to the remote peer if it contains more than zero bytes.
		// Returns 0 if we're done, <0 if we need to continue, and >0 if we need
		// to get more data. Note: remaining size is just a guess.
		// Note that "output" might need to be sent even if we are done.
		int initSession(Engine &e, Buffer &input, Buffer &output, const wchar *host);

		// Accept a session. Works much the same as "initSession", but does not expect "input" to be
		// empty initially.
		int acceptSession(Engine &e, Buffer &input, Buffer &output);

		// Encrypt a message using this session.
		void encrypt(Engine &e, const Buffer &input, Nat inputOffset, Nat inputLength, Buffer &output);

		// Markers from 'decrypt'.
		struct Markers {
			// Start and end of decrypted plaintext.
			Nat plaintextStart;
			Nat plaintextEnd;

			// Start of any remaining data that was not decrypted.
			Nat remainingStart;

			// Is this the end of the connection?
			Bool shutdown;
		};

		// Decrypt a message using this session. Decryption is performed in-place. Returns a set of
		// markers indicating where in the data different parts can be found.
		Markers decrypt(Engine &e, Buffer &data, Nat offset);

		// Shutdown the channel. Returns a message to send to the remote peer.
		Buffer shutdown(Engine &e);

		// Initialize sizes. Called when the context is established.
		void initSizes();

		// Fill the buffers in "data".
		void fill(SChannelData *data);

		// Check the validity of the remote peer's certificate.
		void checkCertificate(Engine &e);
	};


	/**
	 * Client session.
	 */
	class SChannelClientSession : public SChannelSession {
	public:
		SChannelClientSession(SChannelContext *data);

		// Client-side connect.
		virtual void *connect(IStream *input, OStream *output, Str *host);

		// Shutdown.
		virtual void shutdown(void *gcData);
	};

	/**
	 * Server session.
	 */
	class SChannelServerSession : public SChannelSession {
	public:
		SChannelServerSession(SChannelContext *data);

		// Client-side connect.
		virtual void *connect(IStream *input, OStream *output, Str *host);

		// Shutdown.
		virtual void shutdown(void *gcData);
	};
}

#endif