mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Allow certificate based rejection of DO connection attempts.
This commit is contained in:
parent
a9901204e2
commit
d5d8a71c79
8 changed files with 111 additions and 2 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2022-11-21 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/Foundation/NSFileHandle.h:
|
||||
* Headers/GNUstepBase/GSTLS.h:
|
||||
* Source/GSHTTPURLHandle.m:
|
||||
* Source/GSSocketStream.m:
|
||||
* Source/GSTLS.m:
|
||||
* Source/NSURLProtocol.m:
|
||||
* Source/externs.m:
|
||||
Fixup to use strict rfc4514 for distinguished names of issuer and
|
||||
owner of certificates. Add GSTLSIssuers and GSTLSOwners properties
|
||||
to reject remote certificates which do not match distinguishd names
|
||||
accepted. This allows encrypted DO to be configured to automatically
|
||||
reject connection attempts which do not have trusted certificates.
|
||||
|
||||
2022-11-15 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* GSSocketStream.m:
|
||||
|
|
|
@ -324,6 +324,18 @@ GS_EXPORT_CLASS
|
|||
* <desc>A boolean specifying whether diagnostic debug is to be enabled
|
||||
* to log information about a connection where the handshake fails.<br />
|
||||
* </desc>
|
||||
* <term>GSTLSIssuers</term>
|
||||
* <desc>An array of distinguished names (in RFC4514 format) listing the
|
||||
* permitted issuers of the remote certificate. If this is present and the
|
||||
* issuer of the remote certificate is not in the array, the connection
|
||||
* handshake is failed.
|
||||
* </desc>
|
||||
* <term>GSTLSOwners</term>
|
||||
* <desc>An array of distinguished names (in RFC4514 format) listing the
|
||||
* permitted owners/subjects of the remote certificate. If this is present
|
||||
* and the owner/subject of the remote certificate is not in the array, the
|
||||
* connection handshake is failed.
|
||||
* </desc>
|
||||
* <term>GSTLSPriority</term>
|
||||
* <desc>A GNUTLS priority string describing the ciphers etc which may be
|
||||
* used for the connection. In addition the string may be one of
|
||||
|
@ -399,6 +411,14 @@ GS_EXPORT NSString * const GSTLSDebug;
|
|||
*/
|
||||
GS_EXPORT NSString * const GSTLSPriority;
|
||||
|
||||
/** Dictionary key for an array of issuers to use in certificate verification.
|
||||
*/
|
||||
GS_EXPORT NSString * const GSTLSIssuers;
|
||||
|
||||
/** Dictionary key for an array of owners to use in certificate verification.
|
||||
*/
|
||||
GS_EXPORT NSString * const GSTLSOwners;
|
||||
|
||||
/** Dictionary key for a list of hosts to use in certificate verification.
|
||||
*/
|
||||
GS_EXPORT NSString * const GSTLSRemoteHosts;
|
||||
|
|
|
@ -33,6 +33,8 @@ GS_EXPORT NSString * const GSTLSCertificateFile;
|
|||
GS_EXPORT NSString * const GSTLSCertificateKeyFile;
|
||||
GS_EXPORT NSString * const GSTLSCertificateKeyPassword;
|
||||
GS_EXPORT NSString * const GSTLSDebug;
|
||||
GS_EXPORT NSString * const GSTLSIssuers;
|
||||
GS_EXPORT NSString * const GSTLSOwners;
|
||||
GS_EXPORT NSString * const GSTLSPriority;
|
||||
GS_EXPORT NSString * const GSTLSRemoteHosts;
|
||||
GS_EXPORT NSString * const GSTLSRevokeFile;
|
||||
|
|
|
@ -1268,6 +1268,8 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
GSTLSCertificateKeyFile,
|
||||
GSTLSCertificateKeyPassword,
|
||||
GSTLSDebug,
|
||||
GSTLSIssuers,
|
||||
GSTLSOwners,
|
||||
GSTLSPriority,
|
||||
GSTLSRemoteHosts,
|
||||
GSTLSRevokeFile,
|
||||
|
|
|
@ -482,6 +482,8 @@ static NSArray *keys = nil;
|
|||
GSTLSCertificateKeyFile,
|
||||
GSTLSCertificateKeyPassword,
|
||||
GSTLSDebug,
|
||||
GSTLSIssuers,
|
||||
GSTLSOwners,
|
||||
GSTLSPriority,
|
||||
GSTLSRemoteHosts,
|
||||
GSTLSRevokeFile,
|
||||
|
@ -825,6 +827,8 @@ static NSArray *keys = nil;
|
|||
GSTLSCertificateKeyFile,
|
||||
GSTLSCertificateKeyPassword,
|
||||
GSTLSDebug,
|
||||
GSTLSIssuers,
|
||||
GSTLSOwners,
|
||||
GSTLSPriority,
|
||||
GSTLSRemoteHosts,
|
||||
GSTLSRevokeFile,
|
||||
|
|
|
@ -576,8 +576,12 @@ static NSMutableDictionary *certificateListCache = nil;
|
|||
|
||||
+ (void) certInfo: (gnutls_x509_crt_t)cert to: (NSMutableString*)str
|
||||
{
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030507
|
||||
gnutls_datum_t dn;
|
||||
#else
|
||||
char dn[1024];
|
||||
size_t dn_size = sizeof(dn);
|
||||
#endif
|
||||
char serial[40];
|
||||
size_t serial_size = sizeof(serial);
|
||||
time_t expiret;
|
||||
|
@ -589,6 +593,20 @@ static NSMutableDictionary *certificateListCache = nil;
|
|||
[str appendFormat: _(@"- Certificate version: #%d\n"),
|
||||
gnutls_x509_crt_get_version(cert)];
|
||||
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030507
|
||||
if (GNUTLS_E_SUCCESS == gnutls_x509_crt_get_dn3(cert, &dn, 0))
|
||||
{
|
||||
[str appendFormat: @"- Certificate DN: %@\n",
|
||||
[NSString stringWithUTF8String: (const char*)dn.data]];
|
||||
gnutls_free(dn.data);
|
||||
}
|
||||
if (GNUTLS_E_SUCCESS == gnutls_x509_crt_get_issuer_dn3(cert, &dn, 0))
|
||||
{
|
||||
[str appendFormat: _(@"- Certificate Issuer's DN: %@\n"),
|
||||
[NSString stringWithUTF8String: (const char*)dn.data]];
|
||||
gnutls_free(dn.data);
|
||||
}
|
||||
#else
|
||||
dn_size = sizeof(dn) - 1;
|
||||
gnutls_x509_crt_get_dn(cert, dn, &dn_size);
|
||||
dn[dn_size] = '\0';
|
||||
|
@ -600,6 +618,7 @@ static NSMutableDictionary *certificateListCache = nil;
|
|||
dn[dn_size] = '\0';
|
||||
[str appendFormat: _(@"- Certificate Issuer's DN: %@\n"),
|
||||
[NSString stringWithUTF8String: dn]];
|
||||
#endif
|
||||
|
||||
activet = gnutls_x509_crt_get_activation_time(cert);
|
||||
[str appendFormat: _(@"- Certificate is valid since: %s"),
|
||||
|
@ -2447,8 +2466,22 @@ retrieve_callback(gnutls_session_t session,
|
|||
}
|
||||
else
|
||||
{
|
||||
char dn[1024];
|
||||
size_t dn_size;
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030507
|
||||
gnutls_datum_t dn;
|
||||
|
||||
if (GNUTLS_E_SUCCESS == gnutls_x509_crt_get_dn3(cert, &dn, 0))
|
||||
{
|
||||
ASSIGN(owner, [NSString stringWithUTF8String: (const char*)dn.data]);
|
||||
gnutls_free(dn.data);
|
||||
}
|
||||
if (GNUTLS_E_SUCCESS == gnutls_x509_crt_get_issuer_dn3(cert, &dn, 0))
|
||||
{
|
||||
ASSIGN(issuer, [NSString stringWithUTF8String: (const char*)dn.data]);
|
||||
gnutls_free(dn.data);
|
||||
}
|
||||
#else
|
||||
char dn[1024];
|
||||
size_t dn_size;
|
||||
|
||||
/* Get certificate owner and issuer
|
||||
*/
|
||||
|
@ -2461,6 +2494,7 @@ retrieve_callback(gnutls_session_t session,
|
|||
gnutls_x509_crt_get_issuer_dn(cert, dn, &dn_size);
|
||||
dn[dn_size] = '\0';
|
||||
ASSIGN(issuer, [NSString stringWithUTF8String: dn]);
|
||||
#endif
|
||||
}
|
||||
|
||||
str = [opts objectForKey: GSTLSRemoteHosts];
|
||||
|
@ -2503,6 +2537,34 @@ retrieve_callback(gnutls_session_t session,
|
|||
|
||||
gnutls_x509_crt_deinit(cert);
|
||||
|
||||
names = [opts objectForKey: GSTLSIssuers];
|
||||
if ([names isKindOfClass: [NSArray class]])
|
||||
{
|
||||
if (nil == issuer || NO == [names containsObject: issuer])
|
||||
{
|
||||
str = [NSString stringWithFormat:
|
||||
@"TLS verification: certificate's issuer does not match '%@'",
|
||||
names];
|
||||
ASSIGN(problem, str);
|
||||
if (YES == debug) NSLog(@"%p %@", handle, problem);
|
||||
return GNUTLS_E_CERTIFICATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
names = [opts objectForKey: GSTLSOwners];
|
||||
if ([names isKindOfClass: [NSArray class]])
|
||||
{
|
||||
if (nil == owner || NO == [names containsObject: owner])
|
||||
{
|
||||
str = [NSString stringWithFormat:
|
||||
@"TLS verification: certificate's owner does not match '%@'",
|
||||
names];
|
||||
ASSIGN(problem, str);
|
||||
if (YES == debug) NSLog(@"%p %@", handle, problem);
|
||||
return GNUTLS_E_CERTIFICATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // Verified
|
||||
}
|
||||
|
||||
|
|
|
@ -957,6 +957,8 @@ typedef struct {
|
|||
GSTLSCertificateKeyFile,
|
||||
GSTLSCertificateKeyPassword,
|
||||
GSTLSDebug,
|
||||
GSTLSIssuers,
|
||||
GSTLSOwners,
|
||||
GSTLSPriority,
|
||||
GSTLSRemoteHosts,
|
||||
GSTLSRevokeFile,
|
||||
|
|
|
@ -363,6 +363,8 @@ GS_DECLARE NSString* const GSTLSCertificateFile = @"GSTLSCertificateFile";
|
|||
GS_DECLARE NSString* const GSTLSCertificateKeyFile = @"GSTLSCertificateKeyFile";
|
||||
GS_DECLARE NSString* const GSTLSCertificateKeyPassword = @"GSTLSCertificateKeyPassword";
|
||||
GS_DECLARE NSString* const GSTLSDebug = @"GSTLSDebug";
|
||||
GS_DECLARE NSString* const GSTLSIssuers = @"GSTLSIssuers";
|
||||
GS_DECLARE NSString* const GSTLSOwners = @"GSTLSOwners";
|
||||
GS_DECLARE NSString* const GSTLSPriority = @"GSTLSPriority";
|
||||
GS_DECLARE NSString* const GSTLSRemoteHosts = @"GSTLSRemoteHosts";
|
||||
GS_DECLARE NSString* const GSTLSRevokeFile = @"GSTLSRevokeFile";
|
||||
|
|
Loading…
Reference in a new issue