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
{
	return [[[self alloc] initWithClass: class_
				     reason: reason_] autorelease];
}

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

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







|







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

		sock = dup(socket->sock);

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

		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];
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;







|














|







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: [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: [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
		 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];
	}

	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];
	}
}

- (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];
		[newSocket close];
		newSocket->isa = isa;

		@throw [OFAcceptFailedException exceptionWithClass: isa
							    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];
		[newSocket close];
		newSocket->isa = isa;

		@throw [OFAcceptFailedException exceptionWithClass: isa
							    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];

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

	if (atEndOfStream) {
		OFReadFailedException *e;

		e = [OFReadFailedException exceptionWithClass: isa
						       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
							  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];

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

	if (atEndOfStream) {
		OFWriteFailedException *e;

		e = [OFWriteFailedException exceptionWithClass: isa
							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
							   stream: self
						  requestedLength: length];
}

- (size_t)pendingBytes
{
	if (ssl == NULL)







|
>
|
|
|











|
>
|
|
|










|

|

|











|

|

|




















|


|





|












|













|


|





|













|







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: [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: [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 */
		object_setClass(newSocket, [OFTCPSocket class]);
		[newSocket close];
		object_setClass(newSocket, object_getClass(self));

		@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 */
		object_setClass(newSocket, [OFTCPSocket class]);
		[newSocket close];
		object_setClass(newSocket, object_getClass(self));

		@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: [self class]];

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

	if (atEndOfStream) {
		OFReadFailedException *e;

		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: [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: [self class]];

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

	if (atEndOfStream) {
		OFWriteFailedException *e;

		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: [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
- (OFDataArray*)channelBindingDataWithType: (OFString*)type
{
	size_t length;
	char buffer[64];
	OFDataArray *data;

	if (![type isEqual: @"tls-unique"])
		@throw [OFInvalidArgumentException exceptionWithClass: isa

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







|
>
|







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: [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
{
	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
				    reason: [OFString
						stringWithUTF8String: reason]];
	}
}
@end







|





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: [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
		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];
	} @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];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}







|
















|







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

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

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


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








|
>







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: [self class]];

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