ObjOpenSSL  Check-in [8ef0132a06]

Overview
Comment:Don't access isa directly.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 8ef0132a0679382899bb649315c6c8777af0772ffea2353b8fc238750d405804
User & Date: js on 2012-07-12 03:09:43
Other Links: manifest | tags
Context
2012-09-17
14:27
Return 0 on reads where the SSL layer needs more data to proceed check-in: a39f32eccd user: florob@babelmonkeys.de tags: trunk
2012-07-12
03:09
Don't access isa directly. check-in: 8ef0132a06 user: js tags: trunk
2012-06-10
13:34
Adjust to latest ObjFW API changes. check-in: b857e18139 user: js tags: trunk
Changes

Modified src/SSLInvalidCertificateException.m from [c4863306cd] to [d4b845c7e6].

30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44







-
+







{
	return [[[self alloc] initWithClass: class_
				     reason: reason_] autorelease];
}

- initWithClass: (Class)class_
{
	Class c = isa;
	Class c = [self class];
	[self release];
	@throw [OFNotImplementedException exceptionWithClass: c
						    selector: _cmd];
}

- initWithClass: (Class)class_
	 reason: (OFString*)reason_

Modified src/SSLSocket.m from [1bb48d4634] to [0e8016afd9].

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
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







-
+














-
+








		sock = dup(socket->sock);

		if ((ssl = SSL_new(ctx)) == NULL || !SSL_set_fd(ssl, sock)) {
			close(sock);
			sock = INVALID_SOCKET;
			@throw [OFInitializationFailedException
			    exceptionWithClass: isa];
			    exceptionWithClass: [self class]];
		}

		SSL_set_connect_state(ssl);

		if ((privateKeyFile != nil && !SSL_use_PrivateKey_file(ssl,
		    [privateKeyFile cStringWithEncoding:
		    OF_STRING_ENCODING_NATIVE], SSL_FILETYPE_PEM)) ||
		    (certificateFile != nil && !SSL_use_certificate_file(ssl,
		    [certificateFile cStringWithEncoding:
		    OF_STRING_ENCODING_NATIVE], SSL_FILETYPE_PEM)) ||
		    SSL_connect(ssl) != 1) {
			close(sock);
			sock = INVALID_SOCKET;
			@throw [OFInitializationFailedException
			    exceptionWithClass: isa];
			    exceptionWithClass: [self class]];
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
173
174
175
176
177
178
179
180
181
182
183





184
185
186
187
188
189
190
191
192
193
194
195
196
197
198





199
200
201
202
203
204
205
206
207
208
209

210
211

212
213

214
215
216
217
218
219
220
221
222
223
224
225

226
227

228
229

230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253

254
255
256
257
258
259

260
261
262
263
264
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286

287
288
289

290
291
292
293
294
295

296
297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
173
174
175
176
177
178
179




180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195




196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212

213
214

215
216
217
218
219
220
221
222
223
224
225
226

227
228

229
230

231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

252
253
254

255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290

291
292
293
294
295
296

297
298
299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318







-
-
-
-
+
+
+
+
+











-
-
-
-
+
+
+
+
+










-
+

-
+

-
+











-
+

-
+

-
+




















-
+


-
+





-
+












-
+













-
+


-
+





-
+













-
+







		 port: (uint16_t)port
{
	[super connectToHost: host
			port: port];

	if ((ssl = SSL_new(ctx)) == NULL || !SSL_set_fd(ssl, sock)) {
		[super close];
		@throw [OFConnectionFailedException exceptionWithClass: isa
								socket: self
								  host: host
								  port: port];
		@throw [OFConnectionFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host
				  port: port];
	}

	SSL_set_connect_state(ssl);

	if ((privateKeyFile != nil && !SSL_use_PrivateKey_file(ssl,
	    [privateKeyFile cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    SSL_FILETYPE_PEM)) || (certificateFile != nil &&
	    !SSL_use_certificate_file(ssl, [certificateFile
	    cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    SSL_FILETYPE_PEM)) || SSL_connect(ssl) != 1) {
		[super close];
		@throw [OFConnectionFailedException exceptionWithClass: isa
								socket: self
								  host: host
								  port: port];
		@throw [OFConnectionFailedException
		    exceptionWithClass: [self class]
				socket: self
				  host: host
				  port: port];
	}
}

- (SSLSocket*)accept
{
	SSLSocket *newSocket = (SSLSocket*)[super accept];

	if ((newSocket->ssl = SSL_new(ctx)) == NULL ||
	    !SSL_set_fd(newSocket->ssl, newSocket->sock)) {
		/* We only want to close the OFTCPSocket */
		newSocket->isa = [OFTCPSocket class];
		object_setClass(newSocket, [OFTCPSocket class]);
		[newSocket close];
		newSocket->isa = isa;
		object_setClass(newSocket, object_getClass(self));

		@throw [OFAcceptFailedException exceptionWithClass: isa
		@throw [OFAcceptFailedException exceptionWithClass: [self class]
							    socket: self];
	}

	SSL_set_accept_state(newSocket->ssl);

	if (!SSL_use_PrivateKey_file(newSocket->ssl, [privateKeyFile
	    cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    SSL_FILETYPE_PEM) || !SSL_use_certificate_file(newSocket->ssl,
	    [certificateFile cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
	    SSL_FILETYPE_PEM) || SSL_accept(newSocket->ssl) != 1) {
		/* We only want to close the OFTCPSocket */
		newSocket->isa = [OFTCPSocket class];
		object_setClass(newSocket, [OFTCPSocket class]);
		[newSocket close];
		newSocket->isa = isa;
		object_setClass(newSocket, object_getClass(self));

		@throw [OFAcceptFailedException exceptionWithClass: isa
		@throw [OFAcceptFailedException exceptionWithClass: [self class]
							    socket: self];
	}

	return newSocket;
}

- (void)close
{
	if (ssl != NULL)
		SSL_shutdown(ssl);

	[super close];
}

- (size_t)_readIntoBuffer: (void*)buffer
		   length: (size_t)length
{
	ssize_t ret;

	if (length > INT_MAX)
		@throw [OFOutOfRangeException exceptionWithClass: isa];
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	if (sock == INVALID_SOCKET)
		@throw [OFNotConnectedException exceptionWithClass: isa
		@throw [OFNotConnectedException exceptionWithClass: [self class]
							    socket: self];

	if (atEndOfStream) {
		OFReadFailedException *e;

		e = [OFReadFailedException exceptionWithClass: isa
		e = [OFReadFailedException exceptionWithClass: [self class]
						       stream: self
					      requestedLength: length];
#ifndef _WIN32
		e->errNo = ENOTCONN;
#else
		e->errNo = WSAENOTCONN;
#endif

		@throw e;
	}

	if ((ret = SSL_read(ssl, buffer, (int)length)) < 0)
		@throw [OFReadFailedException exceptionWithClass: isa
		@throw [OFReadFailedException exceptionWithClass: [self class]
							  stream: self
						 requestedLength: length];

	if (ret == 0)
		atEndOfStream = YES;

	return ret;
}

- (void)_writeBuffer: (const void*)buffer
	      length: (size_t)length
{
	if (length > INT_MAX)
		@throw [OFOutOfRangeException exceptionWithClass: isa];
		@throw [OFOutOfRangeException exceptionWithClass: [self class]];

	if (sock == INVALID_SOCKET)
		@throw [OFNotConnectedException exceptionWithClass: isa
		@throw [OFNotConnectedException exceptionWithClass: [self class]
							    socket: self];

	if (atEndOfStream) {
		OFWriteFailedException *e;

		e = [OFWriteFailedException exceptionWithClass: isa
		e = [OFWriteFailedException exceptionWithClass: [self class]
							stream: self
					 requestedLength: length];

#ifndef _WIN32
		e->errNo = ENOTCONN;
#else
		e->errNo = WSAENOTCONN;
#endif

		@throw e;
	}

	if (SSL_write(ssl, buffer, (int)length) < length)
		@throw [OFWriteFailedException exceptionWithClass: isa
		@throw [OFWriteFailedException exceptionWithClass: [self class]
							   stream: self
						  requestedLength: length];
}

- (size_t)pendingBytes
{
	if (ssl == NULL)
342
343
344
345
346
347
348
349
350



351
352
353
354
355
356
357
344
345
346
347
348
349
350


351
352
353
354
355
356
357
358
359
360







-
-
+
+
+







- (OFDataArray*)channelBindingDataWithType: (OFString*)type
{
	size_t length;
	char buffer[64];
	OFDataArray *data;

	if (![type isEqual: @"tls-unique"])
		@throw [OFInvalidArgumentException exceptionWithClass: isa
							     selector: _cmd];
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]
			      selector: _cmd];

	if (SSL_session_reused(ssl) ^ !listening) {
		/*
		 * We are either client or the session has been resumed
		 * => we have sent the finished message
		 */
		length = SSL_get_finished(ssl, buffer, 64);
382
383
384
385
386
387
388
389

390
391
392
393
394
385
386
387
388
389
390
391

392
393
394
395
396
397







-
+





{
	unsigned long ret;

	if ((SSL_get_peer_certificate(ssl) == NULL) ||
	    ((ret = SSL_get_verify_result(ssl)) != X509_V_OK)) {
		const char *reason = X509_verify_cert_error_string(ret);
		@throw [SSLInvalidCertificateException
			exceptionWithClass: isa
			exceptionWithClass: [self class]
				    reason: [OFString
						stringWithUTF8String: reason]];
	}
}
@end

Modified src/X509Certificate.m from [a82687bce0] to [9437851e4c].

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
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







-
+
















-
+







		OFDataArray *data = [fd readDataArrayTillEndOfStream];
		[fd close];
		const unsigned char *dataCArray = [data cArray];
		crt = d2i_X509(NULL, &dataCArray, [data count]);
		[pool release];
		if (crt == NULL)
			@throw [OFInitializationFailedException
				    exceptionWithClass: isa];
				    exceptionWithClass: [self class]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithX509Struct: (X509*)cert
{
	self = [self init];

	@try {
		crt = X509_dup(cert);
		if (crt == NULL)
			@throw [OFInitializationFailedException
				    exceptionWithClass: isa];
				    exceptionWithClass: [self class]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
414
415
416
417
418
419
420
421


422
423
424
425
426
427
428
414
415
416
417
418
419
420

421
422
423
424
425
426
427
428
429







-
+
+








- (OFString*)X509_stringFromASN1String: (ASN1_STRING*)str
{
	OFString *ret;
	char *buffer;

	if (ASN1_STRING_to_UTF8((unsigned char**)&buffer, str) < 0)
		@throw [OFInvalidEncodingException exceptionWithClass: isa];
		@throw [OFInvalidEncodingException
		    exceptionWithClass: [self class]];

	@try {
		ret = [OFString stringWithUTF8String: buffer];
	} @finally {
		OPENSSL_free(buffer);
	}