Make TLS client certificate issuer/owner names available

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@40508 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2017-05-19 11:38:48 +00:00
parent e14f82a87f
commit 212861c931
6 changed files with 116 additions and 7 deletions

View file

@ -1,3 +1,13 @@
2017-05-19 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/Foundation/NSFileHandle.h:
* Source/GSSocketStream.m:
* Source/GSTLS.h:
* Source/GSTLS.m:
* Source/NSFileHandle.m:
Add code to make the issuer and owner of a client certificate
available when we require/verify an incoming certificate.
2017-05-10 Wolfgang Lux <wolfgang.lux@gmail.com>
* Tools/gdomap.c (nameServer, donames): Fix incorrect use

View file

@ -263,6 +263,18 @@ GS_EXPORT NSString * const NSFileHandleOperationException;
*/
- (BOOL) sslHandshakeEstablished: (BOOL*)result outgoing: (BOOL)isOutgoing;
/** If the session verified a certificate from the remote end, returns the
* name of the certificate issuer in the form "C=xxxx,O=yyyy,CN=zzzz" as
* described in RFC2253. Otherwise returns nil.
*/
- (NSString*) sslIssuer;
/** If the session verified a certificate from the remote end, returns the
* name of the certificate owner in the form "C=xxxx,O=yyyy,CN=zzzz" as
* described in RFC2253. Otherwise returns nil.
*/
- (NSString*) sslOwner;
/** Deprecated ... use -sslSetOptions: instead
*/
- (void) sslSetCertificate: (NSString*)certFile

View file

@ -358,8 +358,7 @@ GSPrivateSockaddrSetup(NSString *machine, uint16_t port,
GSTLSSession *session;
}
/**
* Populates the dictionary 'dict', copying in all the properties
/** Populates the dictionary 'dict', copying in all the properties
* of the supplied streams. If a property is set for both then
* the output stream's one has precedence.
*/
@ -368,6 +367,11 @@ GSPrivateSockaddrSetup(NSString *machine, uint16_t port,
fromInputStream: (NSStream*)i
orOutputStream: (NSStream*)o;
/** Called on verification of the remote end's certificate to tell the
* delegate of the input stream who the certificate issuer and owner are.
*/
- (void) stream: (NSStream*)stream issuer: (NSString*)i owner: (NSString*)o;
@end
/* Callback to allow the TLS code to pull data from the remote system.
@ -573,6 +577,18 @@ static NSArray *keys = nil;
}
[self bye];
}
else
{
NSString *issuer = [session issuer];
NSString *owner = [session owner];
id del = [istream delegate];
if (nil != issuer && nil != owner
&& [del respondsToSelector: @selector(stream:issuer:owner:)])
{
[del stream: istream issuer: issuer owner: owner];
}
}
}
}
}
@ -718,6 +734,11 @@ static NSArray *keys = nil;
}
}
- (void) stream: (NSStream*)stream issuer: (NSString*)i owner: (NSString*)o
{
return;
}
- (NSInteger) write: (const uint8_t *)buffer maxLength: (NSUInteger)len
{
return [session write: buffer length: len];

View file

@ -184,6 +184,8 @@ typedef ssize_t (*GSTLSIOW)(gnutls_transport_ptr_t, const void *, size_t);
NSDictionary *opts;
GSTLSCredentials *credentials;
NSString *problem;
NSString *issuer;
NSString *owner;
BOOL outgoing;
BOOL active;
BOOL handshake;
@ -230,6 +232,18 @@ typedef ssize_t (*GSTLSIOW)(gnutls_transport_ptr_t, const void *, size_t);
*/
- (BOOL) handshake;
/** If the session verified a certificate from the remote end, returns the
* name of the certificate issuer in the form "C=xxxx,O=yyyy,CN=zzzz" as
* described in RFC2253. Otherwise returns nil.
*/
- (NSString*) issuer;
/** If the session verified a certificate from the remote end, returns the
* name of the certificate owner in the form "C=xxxx,O=yyyy,CN=zzzz" as
* described in RFC2253. Otherwise returns nil.
*/
- (NSString*) owner;
/* After a failed handshake, this should contain a description of the
* failure reason.
*/

View file

@ -160,7 +160,7 @@ static NSString *revokeFile = nil; // GSTLS/revoke.crl
/* The verifyClient variable tells us if connections from a remote server
* should (by default) require and verify a client certificate against
* trusted authorities.
* our trusted authorities.
* The hard-coded value can be overridden by the GS_TLS_VERIFY_C environment
* variable, which in turn will be overridden by the GSTLSVerifyClient user
* default string.
@ -168,8 +168,9 @@ static NSString *revokeFile = nil; // GSTLS/revoke.crl
*/
static BOOL verifyClient = NO;
/* The verifyServer variable tells us if connections to a remote server should
* (by default) verify its certificate against trusted authorities.
/* The verifyServer variable tells us if outgoing connections (as a client)
* to a remote server should (by default) verify that server's certificate
* against trusted authorities.
* The hard-coded value can be overridden by the GS_TLS_VERIFY_S environment
* variable, which in turn will be overridden by the GSTLSVerifyServer user
* default string.
@ -1430,6 +1431,8 @@ retrieve_callback(gnutls_session_t session,
DESTROY(opts);
DESTROY(credentials);
DESTROY(problem);
DESTROY(issuer);
DESTROY(owner);
[super dealloc];
}
@ -1803,6 +1806,16 @@ retrieve_callback(gnutls_session_t session,
}
}
- (NSString*) issuer
{
return issuer;
}
- (NSString*) owner
{
return owner;
}
- (NSString*) problem
{
return problem;
@ -2113,13 +2126,15 @@ retrieve_callback(gnutls_session_t session,
if (status & GNUTLS_CERT_REVOKED)
NSLog(@"%@ TLS verification: certificate has been revoked.", self);
/*
#if defined(GNUTLS_CERT_EXPIRED)
if (status & GNUTLS_CERT_EXPIRED)
NSLog(@"%@ TLS verification: certificate has expired", self);
#endif
#if defined(GNUTLS_CERT_NOT_ACTIVATED)
if (status & GNUTLS_CERT_NOT_ACTIVATED)
NSLog(@"%@ TLS verification: certificate is not yet activated", self);
*/
#endif
}
if (status & GNUTLS_CERT_INVALID)
@ -2166,6 +2181,23 @@ retrieve_callback(gnutls_session_t session,
if (YES == debug) NSLog(@"%@ %@", self, problem);
return GNUTLS_E_CERTIFICATE_ERROR;
}
else
{
char dn[1024];
size_t dn_size;
/* Get certificate owner and issuer
*/
dn_size = sizeof(dn);
gnutls_x509_crt_get_dn(cert, dn, &dn_size);
dn[dn_size - 1] = '\0';
ASSIGN(owner, [NSString stringWithUTF8String: dn]);
dn_size = sizeof(dn);
gnutls_x509_crt_get_issuer_dn(cert, dn, &dn_size);
dn[dn_size - 1] = '\0';
ASSIGN(issuer, [NSString stringWithUTF8String: dn]);
}
str = [opts objectForKey: GSTLSRemoteHosts];
if (nil == str)

View file

@ -848,6 +848,16 @@ NSString * const NSFileHandleOperationException
return YES;
}
- (NSString*) sslIssuer
{
return nil;
}
- (NSString*) sslOwner
{
return nil;
}
- (void) sslSetCertificate: (NSString*)certFile
privateKey: (NSString*)privateKey
PEMpasswd: (NSString*)PEMpasswd
@ -1045,6 +1055,16 @@ GSTLSHandlePush(gnutls_transport_ptr_t handle, const void *buffer, size_t len)
}
}
- (NSString*) sslIssuer
{
return [session issuer];
}
- (NSString*) sslOwner
{
return [session owner];
}
- (NSString*) sslSetOptions: (NSDictionary*)options
{
if (isStandardFile == YES)