Add methods enabling certificate verification

This commit is contained in:
Florian Zeitz 2011-10-24 01:39:48 +02:00
parent a4ab82d900
commit 8a7c60fe1c
4 changed files with 153 additions and 0 deletions

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
*
* https://webkeks.org/hg/objopenssl/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#import <ObjFW/OFString.h>
#import <ObjFW/OFException.h>
@interface SSLInvalidCertificateException: OFException
{
OFString *reason;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, nonatomic) OFString *reason;
#endif
+ exceptionWithClass: (Class)class
reason: (OFString*)reason;
- initWithClass: (Class)class
reason: (OFString*)reason;
- (OFString*)reason;
@end

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
*
* https://webkeks.org/hg/objopenssl/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#import "SSLInvalidCertificateException.h"
#import <ObjFW/OFNotImplementedException.h>
@implementation SSLInvalidCertificateException
+ exceptionWithClass: (Class)class_
reason: (OFString*)reason_;
{
return [[self alloc] initWithClass: class_
reason: reason_];
}
- initWithClass: (Class)class_
{
Class c = isa;
[self release];
@throw [OFNotImplementedException exceptionWithClass: c
selector: _cmd];
}
- initWithClass: (Class)class_
reason: (OFString*)reason_
{
self = [super initWithClass: class_];
@try {
reason = [reason_ copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[reason release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Invalid certificate, Reason: %@!", reason];
return description;
}
- (OFString*)reason
{
return reason;
}
@end

View file

@ -24,6 +24,8 @@
#import <ObjFW/OFTCPSocket.h>
@class X509Certificate;
@interface SSLSocket: OFTCPSocket
{
SSL *ssl;
@ -44,4 +46,6 @@
- (void)setCertificateFile: (OFString*)file;
- (OFString*)certificateFile;
- (OFDataArray*)channelBindingDataWithType: (OFString*)type;
- (X509Certificate*)peerCertificate;
- (void)verifyPeerCertificate;
@end

View file

@ -28,8 +28,11 @@
#import <ObjFW/OFDataArray.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#import "SSLSocket.h"
#import "SSLInvalidCertificateException.h"
#import "X509Certificate.h"
#import <ObjFW/OFAcceptFailedException.h>
#import <ObjFW/OFConnectionFailedException.h>
@ -95,6 +98,10 @@ ssl_locking_callback(int mode, int n, const char *file, int line)
if ((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) == 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
if (SSL_CTX_set_default_verify_paths(ctx) == 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
- initWithSocket: (OFTCPSocket*)socket
@ -343,4 +350,27 @@ ssl_locking_callback(int mode, int n, const char *file, int line)
return data;
}
- (X509Certificate*)peerCertificate
{
X509 *certificate = SSL_get_peer_certificate(ssl);
if (!certificate)
return nil;
return [[[X509Certificate alloc]
initWithStruct: certificate] autorelease];
}
- (void)verifyPeerCertificate
{
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