Skip to content
This repository was archived by the owner on Dec 2, 2024. It is now read-only.

Commit 272a6f4

Browse files
committed
Add SSLConnectionFailedException
This way, when an SSLSocket is passed where an OFTCPSocket is expected, the description will still contain the error and no special code for SSLSocket is necessary.
1 parent 7c85e21 commit 272a6f4

6 files changed

Lines changed: 241 additions & 14 deletions

File tree

Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<key>CFBundleExecutable</key>
66
<string>${EXECUTABLE_NAME}</string>
77
<key>CFBundleIdentifier</key>
8-
<string>zone.heap.${PRODUCT_NAME:rfc1034identifier}</string>
8+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
99
<key>CFBundleInfoDictionaryVersion</key>
1010
<string>6.0</string>
1111
<key>CFBundleName</key>

ObjOpenSSL.xcodeproj/project.pbxproj

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
4B9671B6193E55C800F9F80D /* ObjFW.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B9671B5193E55C800F9F80D /* ObjFW.framework */; };
1616
4BD0AAEC1341289500445289 /* SSLSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD0AAEA1341289500445289 /* SSLSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
1717
4BD0AAED1341289500445289 /* SSLSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD0AAEB1341289500445289 /* SSLSocket.m */; };
18+
4BDE04741D319BFC0051EDB8 /* SSLConnectionFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BDE04721D319BFC0051EDB8 /* SSLConnectionFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; };
19+
4BDE04751D319BFC0051EDB8 /* SSLConnectionFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDE04731D319BFC0051EDB8 /* SSLConnectionFailedException.m */; };
1820
/* End PBXBuildFile section */
1921

2022
/* Begin PBXFileReference section */
@@ -28,6 +30,8 @@
2830
4BD0AAE91341286B00445289 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
2931
4BD0AAEA1341289500445289 /* SSLSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SSLSocket.h; path = src/SSLSocket.h; sourceTree = SOURCE_ROOT; };
3032
4BD0AAEB1341289500445289 /* SSLSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SSLSocket.m; path = src/SSLSocket.m; sourceTree = SOURCE_ROOT; };
33+
4BDE04721D319BFC0051EDB8 /* SSLConnectionFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SSLConnectionFailedException.h; path = src/SSLConnectionFailedException.h; sourceTree = SOURCE_ROOT; };
34+
4BDE04731D319BFC0051EDB8 /* SSLConnectionFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SSLConnectionFailedException.m; path = src/SSLConnectionFailedException.m; sourceTree = SOURCE_ROOT; };
3135
/* End PBXFileReference section */
3236

3337
/* Begin PBXFrameworksBuildPhase section */
@@ -72,6 +76,8 @@
7276
children = (
7377
4B1918F41341272300D82152 /* Supporting Files */,
7478
4B4F087713A01EEF00B60C3F /* ObjOpenSSL.h */,
79+
4BDE04721D319BFC0051EDB8 /* SSLConnectionFailedException.h */,
80+
4BDE04731D319BFC0051EDB8 /* SSLConnectionFailedException.m */,
7581
4B19F58714D17250005D52DC /* SSLInvalidCertificateException.h */,
7682
4B19F58814D17250005D52DC /* SSLInvalidCertificateException.m */,
7783
4BD0AAEA1341289500445289 /* SSLSocket.h */,
@@ -98,6 +104,7 @@
98104
buildActionMask = 2147483647;
99105
files = (
100106
4B4F087813A01EEF00B60C3F /* ObjOpenSSL.h in Headers */,
107+
4BDE04741D319BFC0051EDB8 /* SSLConnectionFailedException.h in Headers */,
101108
4B19F58B14D17250005D52DC /* SSLInvalidCertificateException.h in Headers */,
102109
4BD0AAEC1341289500445289 /* SSLSocket.h in Headers */,
103110
4B19F58D14D17250005D52DC /* X509Certificate.h in Headers */,
@@ -131,7 +138,7 @@
131138
4B1918E01341272300D82152 /* Project object */ = {
132139
isa = PBXProject;
133140
attributes = {
134-
LastUpgradeCheck = 0510;
141+
LastUpgradeCheck = 0730;
135142
};
136143
buildConfigurationList = 4B1918E31341272300D82152 /* Build configuration list for PBXProject "ObjOpenSSL" */;
137144
compatibilityVersion = "Xcode 3.2";
@@ -165,6 +172,7 @@
165172
isa = PBXSourcesBuildPhase;
166173
buildActionMask = 2147483647;
167174
files = (
175+
4BDE04751D319BFC0051EDB8 /* SSLConnectionFailedException.m in Sources */,
168176
4B19F58C14D17250005D52DC /* SSLInvalidCertificateException.m in Sources */,
169177
4BD0AAED1341289500445289 /* SSLSocket.m in Sources */,
170178
4B19F58E14D17250005D52DC /* X509Certificate.m in Sources */,
@@ -177,6 +185,7 @@
177185
4B1918FA1341272300D82152 /* Debug */ = {
178186
isa = XCBuildConfiguration;
179187
buildSettings = {
188+
ENABLE_TESTABILITY = YES;
180189
GCC_C_LANGUAGE_STANDARD = gnu99;
181190
GCC_OPTIMIZATION_LEVEL = 0;
182191
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
@@ -224,6 +233,7 @@
224233
"-lcrypto",
225234
"-lz",
226235
);
236+
PRODUCT_BUNDLE_IDENTIFIER = "zone.heap.${PRODUCT_NAME:rfc1034identifier}";
227237
PRODUCT_NAME = "$(TARGET_NAME)";
228238
WARNING_CFLAGS = (
229239
"-Wall",
@@ -263,6 +273,7 @@
263273
"-lcrypto",
264274
"-lz",
265275
);
276+
PRODUCT_BUNDLE_IDENTIFIER = "zone.heap.${PRODUCT_NAME:rfc1034identifier}";
266277
PRODUCT_NAME = "$(TARGET_NAME)";
267278
WARNING_CFLAGS = (
268279
"-Wall",

src/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ STATIC_LIB = ${OBJOPENSSL_STATIC_LIB}
55
LIB_MAJOR = 0
66
LIB_MINOR = 0
77

8-
SRCS = SSLInvalidCertificateException.m \
8+
SRCS = SSLConnectionFailedException.m \
9+
SSLInvalidCertificateException.m \
910
SSLSocket.m \
1011
X509Certificate.m
1112

src/SSLConnectionFailedException.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (c) 2016, Jonathan Schleifer <js@heap.zone>
3+
*
4+
* https://heap.zone/git/?p=objopenssl.git
5+
*
6+
* Permission to use, copy, modify, and/or distribute this software for any
7+
* purpose with or without fee is hereby granted, provided that the above
8+
* copyright notice and this permission notice is present in all copies.
9+
*
10+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
11+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
14+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
15+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
16+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
17+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
18+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
20+
* POSSIBILITY OF SUCH DAMAGE.
21+
*/
22+
23+
#import <ObjFW/OFConnectionFailedException.h>
24+
25+
@class SSLSocket;
26+
27+
@interface SSLConnectionFailedException: OFConnectionFailedException
28+
{
29+
unsigned long _SSLError;
30+
long _verifyResult;
31+
}
32+
33+
@property (readonly) unsigned long SSLError;
34+
@property (readonly) long verifyResult;
35+
36+
+ (instancetype)exceptionWithHost: (OFString*)host
37+
port: (uint16_t)port
38+
socket: (SSLSocket*)socket
39+
SSLError: (unsigned long)SSLError;
40+
+ (instancetype)exceptionWithHost: (OFString*)host
41+
port: (uint16_t)port
42+
socket: (SSLSocket*)socket
43+
SSLError: (unsigned long)SSLError
44+
verifyResult: (long)verifyResult;
45+
- initWithHost: (OFString*)host
46+
port: (uint16_t)port
47+
socket: (SSLSocket*)socket
48+
SSLError: (unsigned long)SSLError;
49+
- initWithHost: (OFString*)host
50+
port: (uint16_t)port
51+
socket: (SSLSocket*)socket
52+
SSLError: (unsigned long)SSLError
53+
verifyResult: (long)verifyResult;
54+
@end

src/SSLConnectionFailedException.m

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright (c) 2016, Jonathan Schleifer <js@heap.zone>
3+
*
4+
* https://heap.zone/git/?p=objopenssl.git
5+
*
6+
* Permission to use, copy, modify, and/or distribute this software for any
7+
* purpose with or without fee is hereby granted, provided that the above
8+
* copyright notice and this permission notice is present in all copies.
9+
*
10+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
11+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
14+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
15+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
16+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
17+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
18+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
20+
* POSSIBILITY OF SUCH DAMAGE.
21+
*/
22+
23+
#include <inttypes.h>
24+
25+
#import <ObjFW/OFString.h>
26+
27+
#import "SSLConnectionFailedException.h"
28+
29+
#if defined(__clang__)
30+
# pragma clang diagnostic push
31+
# pragma clang diagnostic ignored "-Wdocumentation"
32+
#endif
33+
34+
#include <openssl/err.h>
35+
#include <openssl/ssl.h>
36+
#include <openssl/x509v3.h>
37+
38+
#if defined(__clang__)
39+
# pragma clang diagnostic pop
40+
#endif
41+
42+
@implementation SSLConnectionFailedException
43+
@synthesize SSLError = _SSLError, verifyResult = _verifyResult;
44+
45+
+ (instancetype)exceptionWithHost: (OFString*)host
46+
port: (uint16_t)port
47+
socket: (SSLSocket*)socket
48+
SSLError: (unsigned long)SSLError
49+
{
50+
return [[[self alloc] initWithHost: host
51+
port: port
52+
socket: socket
53+
SSLError: SSLError] autorelease];
54+
}
55+
56+
57+
+ (instancetype)exceptionWithHost: (OFString*)host
58+
port: (uint16_t)port
59+
socket: (SSLSocket*)socket
60+
SSLError: (unsigned long)SSLError
61+
verifyResult: (long)verifyResult
62+
{
63+
return [[[self alloc] initWithHost: host
64+
port: port
65+
socket: socket
66+
SSLError: SSLError
67+
verifyResult: verifyResult] autorelease];
68+
}
69+
70+
- initWithHost: (OFString*)host
71+
port: (uint16_t)port
72+
socket: (SSLSocket*)socket
73+
SSLError: (unsigned long)SSLError
74+
{
75+
self = [super initWithHost: host
76+
port: port
77+
socket: socket];
78+
79+
_SSLError = SSLError;
80+
81+
return self;
82+
}
83+
84+
- initWithHost: (OFString*)host
85+
port: (uint16_t)port
86+
socket: (SSLSocket*)socket
87+
SSLError: (unsigned long)SSLError
88+
verifyResult: (long)verifyResult
89+
{
90+
self = [super initWithHost: host
91+
port: port
92+
socket: socket];
93+
94+
_SSLError = SSLError;
95+
_verifyResult = verifyResult;
96+
97+
return self;
98+
}
99+
100+
- (OFString*)description
101+
{
102+
if (_SSLError != SSL_ERROR_NONE) {
103+
char error[512];
104+
105+
ERR_error_string_n(_SSLError, error, 512);
106+
107+
if (_verifyResult != X509_V_OK)
108+
return [OFString stringWithFormat:
109+
@"A connection to %@ on port %" @PRIu16 @" could "
110+
@"not be established in socket of type %@: "
111+
@"Verification failed: %s [%s]",
112+
_host, _port, [_socket class],
113+
X509_verify_cert_error_string(_verifyResult),
114+
error];
115+
else
116+
return [OFString stringWithFormat:
117+
@"A connection to %@ on port %" @PRIu16 @" could "
118+
@"not be established in socket of type %@: %s",
119+
_host, _port, [_socket class], error];
120+
}
121+
122+
return [super description];
123+
}
124+
@end

src/SSLSocket.m

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
#include <openssl/crypto.h>
3636
#include <openssl/err.h>
37+
#include <openssl/ssl.h>
3738
#include <openssl/x509v3.h>
3839

3940
#if defined(__clang__)
@@ -46,7 +47,6 @@
4647
#import <ObjFW/OFSystemInfo.h>
4748

4849
#import <ObjFW/OFAcceptFailedException.h>
49-
#import <ObjFW/OFConnectionFailedException.h>
5050
#import <ObjFW/OFInitializationFailedException.h>
5151
#import <ObjFW/OFInvalidArgumentException.h>
5252
#import <ObjFW/OFNotOpenException.h>
@@ -58,9 +58,11 @@
5858
#import <ObjFW/threading.h>
5959

6060
#import "SSLSocket.h"
61-
#import "SSLInvalidCertificateException.h"
6261
#import "X509Certificate.h"
6362

63+
#import "SSLConnectionFailedException.h"
64+
#import "SSLInvalidCertificateException.h"
65+
6466
#ifndef INVALID_SOCKET
6567
# define INVALID_SOCKET -1
6668
#endif
@@ -175,12 +177,16 @@ - (void)SSL_startTLSWithExpectedHost: (OFString*)host
175177
{
176178
of_string_encoding_t encoding;
177179

178-
if ((_SSL = SSL_new(ctx)) == NULL || !SSL_set_fd(_SSL, _socket)) {
180+
if ((_SSL = SSL_new(ctx)) == NULL || SSL_set_fd(_SSL, _socket) != 1) {
181+
unsigned long error = ERR_get_error();
182+
179183
[super close];
180-
@throw [OFConnectionFailedException
184+
185+
@throw [SSLConnectionFailedException
181186
exceptionWithHost: host
182187
port: port
183-
socket: self];
188+
socket: self
189+
SSLError: error];
184190
}
185191

186192
if (_certificateVerificationEnabled) {
@@ -190,11 +196,17 @@ - (void)SSL_startTLSWithExpectedHost: (OFString*)host
190196
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
191197

192198
if (X509_VERIFY_PARAM_set1_host(param,
193-
[host UTF8String], [host UTF8StringLength]) == 0)
194-
@throw [OFConnectionFailedException
199+
[host UTF8String], [host UTF8StringLength]) != 1) {
200+
unsigned long error = ERR_get_error();
201+
202+
[self close];
203+
204+
@throw [SSLConnectionFailedException
195205
exceptionWithHost: host
196206
port: port
197-
socket: self];
207+
socket: self
208+
SSLError: error];
209+
}
198210

199211
SSL_set_verify(_SSL, SSL_VERIFY_PEER, NULL);
200212
}
@@ -208,12 +220,37 @@ - (void)SSL_startTLSWithExpectedHost: (OFString*)host
208220
SSL_FILETYPE_PEM)) || (_certificateFile != nil &&
209221
!SSL_use_certificate_file(_SSL, [_certificateFile
210222
cStringWithEncoding: encoding],
211-
SSL_FILETYPE_PEM)) || SSL_connect(_SSL) != 1) {
223+
SSL_FILETYPE_PEM))) {
224+
unsigned long error = ERR_get_error();
225+
212226
[super close];
213-
@throw [OFConnectionFailedException
227+
228+
@throw [SSLConnectionFailedException
214229
exceptionWithHost: host
215230
port: port
216-
socket: self];
231+
socket: self
232+
SSLError: error];
233+
}
234+
235+
if (SSL_connect(_SSL) != 1) {
236+
unsigned long error = ERR_get_error();
237+
long res;
238+
239+
[super close];
240+
241+
if ((res = SSL_get_verify_result(_SSL)) != X509_V_OK)
242+
@throw [SSLConnectionFailedException
243+
exceptionWithHost: host
244+
port: port
245+
socket: self
246+
SSLError: error
247+
verifyResult: res];
248+
else
249+
@throw [SSLConnectionFailedException
250+
exceptionWithHost: host
251+
port: port
252+
socket: self
253+
SSLError: error];
217254
}
218255
}
219256

0 commit comments

Comments
 (0)