Add diagnostic code

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@40067 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2016-09-02 07:59:08 +00:00
parent 08f141ad80
commit e5f00ce4cc
3 changed files with 201 additions and 62 deletions

View file

@ -716,14 +716,15 @@ static NSMutableDictionary *certificateListCache = nil;
[l release];
return nil;
}
l->crts = malloc(sizeof(gnutls_x509_crt_t) * count);
memcpy(l->crts, crts, sizeof(gnutls_x509_crt_t) * count);
l->count = count;
if (count > 0)
{
time_t now = (time_t)[[NSDate date] timeIntervalSince1970];
unsigned int i;
unsigned int i = count;
l->crts = malloc(sizeof(gnutls_x509_crt_t) * count);
memcpy(l->crts, crts, sizeof(gnutls_x509_crt_t) * count);
l->count = count;
for (i = 0; i < count; i++)
{
@ -778,9 +779,9 @@ static NSMutableDictionary *certificateListCache = nil;
{
while (count-- > 0)
{
gnutls_x509_crt_deinit(crts[count]);
if (crts) gnutls_x509_crt_deinit(crts[count]);
}
free(crts);
if (crts) free(crts);
}
}
[super dealloc];
@ -1193,7 +1194,7 @@ static NSMutableDictionary *credentialsCache = nil;
}
}
/* Load our certificate (may be a list) ifthe file is specified.
/* Load our certificate (may be a list) if the file is specified.
*/
if (nil != cf)
{
@ -1262,6 +1263,16 @@ static NSMutableDictionary *credentialsCache = nil;
return certcred;
}
- (GSTLSPrivateKey*) key
{
return key;
}
- (GSTLSCertificateList*) list
{
return list;
}
- (BOOL) trust
{
return trust;
@ -1269,7 +1280,83 @@ static NSMutableDictionary *credentialsCache = nil;
@end
/* Callback used only when debug is enabled, to print the request for a
* certificate and the response to that request.
* NB. This function always returns the certificate set for the session
* even if that certificate does not match the CAs or algorithms requested
* by the server. This differs from the default behavior which is for the
* library code to only return a certificate matching the request.
* So, the logging of a returned certificate does not guarantee that the
* certificate is acceptable to the server.
*/
static int
retrieve_callback(gnutls_session_t session,
const gnutls_datum_t *req_ca_rdn,
int nreqs,
const gnutls_pk_algorithm_t *sign_algos,
int sign_algos_length,
gnutls_retr2_st *st)
{
GSTLSSession *s = gnutls_session_get_ptr(session);
char issuer_dn[256];
int i;
int ret;
size_t len;
/* Print the server's trusted CAs
*/
if (nreqs > 0)
NSLog(@"- Server's trusted authorities:");
else
NSLog(@"- Server did not send us any trusted authorities names.");
/* print the names (if any) */
for (i = 0; i < nreqs; i++)
{
len = sizeof(issuer_dn);
ret = gnutls_x509_rdn_get(&req_ca_rdn[i], issuer_dn, &len);
if (ret >= 0)
{
NSLog(@" [%d]: %s", i, issuer_dn);
}
}
/* Select a certificate and return it.
* The certificate must be of any of the "sign algorithms"
* supported by the server.
*/
if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509)
{
GSTLSCredentials *credentials = [s credentials];
GSTLSPrivateKey *key = [credentials key];
GSTLSCertificateList *list = [credentials list];
int count = (int)[list count];
gnutls_x509_crt_t *crts = [list certificateList];
NSMutableString *m;
m = [NSMutableString stringWithCapacity: 2000];
for (i = 0; i < count; i++)
{
[GSTLSCertificateList certInfo: crts[i]
to: m];
}
if (0 == count)
{
[m appendString: @"None."];
}
NSLog(@"Certificates retrieved for sending to peer -\n%@", m);
st->cert_type = GNUTLS_CRT_X509;
st->ncerts = count;
st->cert.x509 = crts;
st->key.x509 = [key key];
return 0;
}
else
{
return -1;
}
}
@implementation GSTLSSession
@ -1294,6 +1381,11 @@ static NSMutableDictionary *credentialsCache = nil;
return active;
}
- (GSTLSCredentials*) credentials
{
return credentials;
}
- (void) dealloc
{
[self finalize];
@ -1303,6 +1395,11 @@ static NSMutableDictionary *credentialsCache = nil;
[super dealloc];
}
- (BOOL) debug
{
return debug;
}
- (BOOL) disconnect: (BOOL)reusable
{
BOOL ok = YES;
@ -1407,6 +1504,11 @@ static NSMutableDictionary *credentialsCache = nil;
gnutls_certificate_server_set_request(session,
GNUTLS_CERT_IGNORE);
}
else
{
gnutls_certificate_server_set_request(session,
GNUTLS_CERT_REQUEST);
}
}
setup = YES;
@ -1447,7 +1549,7 @@ static NSMutableDictionary *credentialsCache = nil;
@" the GS_TLS_CA_FILE environment variable, then the system will"
@" have attempted to use the GSTLS/ca-certificates.crt file in the"
@" gnustep-base resource bundle. Unfortunately, it has not been"
@" possible to ready any trusted certificate authoritied from"
@" possible to read any trusted certificate authorities from"
@" these locations.");
}
@ -1538,6 +1640,17 @@ static NSMutableDictionary *credentialsCache = nil;
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
[credentials credentials]);
if (YES == outgoing && YES == debug)
{
/* Set a callback to log handling of a request (from the server)
* for the client certificate. The callback always returns the
* certificate set for this session, even if that does not match
* the server's request.
*/
gnutls_certificate_set_retrieve_function(
[credentials credentials], retrieve_callback);
}
/* Set transport layer to use
*/
#if GNUTLS_VERSION_NUMBER < 0x020C00
@ -1546,6 +1659,7 @@ static NSMutableDictionary *credentialsCache = nil;
gnutls_transport_set_pull_function(session, pullFunc);
gnutls_transport_set_push_function(session, pushFunc);
gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)handle);
gnutls_session_set_ptr(session, (void*)self);
}
return self;
@ -1824,54 +1938,26 @@ static NSMutableDictionary *credentialsCache = nil;
break;
case GNUTLS_CRD_CERTIFICATE: /* certificate authentication */
{
unsigned int cert_list_size = 0;
const gnutls_datum_t *cert_list;
gnutls_x509_crt_t cert;
/* Check if we have been using ephemeral Diffie-Hellman.
*/
if (GNUTLS_KX_DHE_RSA == kx || GNUTLS_KX_DHE_DSS == kx)
{
dhe = 1;
ecdh = 0;
}
/* Check if we have been using ephemeral Diffie-Hellman.
*/
if (GNUTLS_KX_DHE_RSA == kx || GNUTLS_KX_DHE_DSS == kx)
{
dhe = 1;
ecdh = 0;
}
#if 0
if (GNUTLS_KX_ECDHE_RSA == kx || GNUTLS_KX_ECDHE_ECDSA == kx)
{
dhe = 0;
ecdh = 1;
}
if (GNUTLS_KX_ECDHE_RSA == kx || GNUTLS_KX_ECDHE_ECDSA == kx)
{
dhe = 0;
ecdh = 1;
}
#endif
/* if the certificate list is available, then
* print some information about it.
*/
cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
if (cert_list_size > 0
&& gnutls_certificate_type_get(session) == GNUTLS_CRT_X509)
{
int cert_num;
for (cert_num = 0; cert_num < cert_list_size; cert_num++)
{
gnutls_x509_crt_init(&cert);
/* NB. the list of peer certificate is in memory in native
* format (DER) rather than the normal file format (PEM).
*/
gnutls_x509_crt_import(cert,
&cert_list[cert_num], GNUTLS_X509_FMT_DER);
tmp = gnutls_certificate_type_get_name(
gnutls_certificate_type_get(session));
[str appendFormat: _(@"- Authentication using certificate type: %s\n"),
tmp];
[str appendString: @"\n"];
[str appendFormat: _(@"- Certificate %d info:\n"), cert_num];
[GSTLSCertificateList certInfo: cert to: str];
gnutls_x509_crt_deinit(cert);
}
}
}
break;
break;
} /* switch */
if (ecdh != 0)
@ -1889,16 +1975,52 @@ static NSMutableDictionary *credentialsCache = nil;
gnutls_dh_get_prime_bits(session)];
}
/* print the protocol's name (ie TLS 1.0)
/* print the protocol's name (eg TLS 1.0)
*/
tmp = gnutls_protocol_get_name(gnutls_protocol_get_version(session));
[str appendFormat: _(@"- Protocol: %s\n"), tmp];
/* print the certificate type of the peer.
* ie X.509
/* print the certificates of the peer.
*/
tmp = gnutls_certificate_type_get_name(gnutls_certificate_type_get(session));
[str appendFormat: _(@"- Certificate Type: %s\n"), tmp];
if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509)
{
unsigned int cert_list_size = 0;
const gnutls_datum_t *cert_list;
gnutls_x509_crt_t cert;
cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
if (0 == cert_list_size)
{
[str appendString: _(@"- Peer provided no certificate.\n")];
}
else
{
int cert_num;
for (cert_num = 0; cert_num < cert_list_size; cert_num++)
{
gnutls_x509_crt_init(&cert);
/* NB. the list of peer certificate is in memory in native
* format (DER) rather than the normal file format (PEM).
*/
gnutls_x509_crt_import(cert,
&cert_list[cert_num], GNUTLS_X509_FMT_DER);
[str appendString: @"\n"];
[str appendFormat: _(@"- Certificate %d info:\n"), cert_num];
[GSTLSCertificateList certInfo: cert to: str];
gnutls_x509_crt_deinit(cert);
}
}
}
else
{
tmp = gnutls_certificate_type_get_name(
gnutls_certificate_type_get(session));
[str appendFormat: _(@"- Certificate Type: %s\n"), tmp];
}
/* print the compression algorithm (if any)
*/
@ -1906,13 +2028,13 @@ static NSMutableDictionary *credentialsCache = nil;
[str appendFormat: _(@"- Compression: %s\n"), tmp];
/* print the name of the cipher used.
* ie 3DES.
* eg 3DES.
*/
tmp = gnutls_cipher_get_name(gnutls_cipher_get(session));
[str appendFormat: _(@"- Cipher: %s\n"), tmp];
/* Print the MAC algorithms name.
* ie SHA1
* eg SHA1
*/
tmp = gnutls_mac_get_name(gnutls_mac_get(session));
[str appendFormat: _(@"- MAC: %s\n"), tmp];
@ -1933,7 +2055,7 @@ static NSMutableDictionary *credentialsCache = nil;
/* This verification function uses the trusted CAs in the credentials
* structure. So you must have installed one or more CA certificates.
*/
ret = gnutls_certificate_verify_peers2 (session, &status);
ret = gnutls_certificate_verify_peers2(session, &status);
if (ret < 0)
{
str = [NSString stringWithFormat: