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:
rfm 2016-09-02 07:59:08 +00:00
parent 7c5b9e3cd5
commit 59c2bc24a4
3 changed files with 201 additions and 62 deletions

View file

@ -5,7 +5,7 @@ ca-certificates.crt
a list of PEM encoded certificates of trusted authorities
NB. This is just the list of trusted authorities from my personal
machine, it may bot be suitable for you ... please replace/remove
machine, it may not be suitable for you ... please replace/remove
to meet your own needs.
revoke.crl

View file

@ -116,8 +116,15 @@ extern NSString * const GSTLSVerify;
unsigned int count;
}
+ (GSTLSCertificateList*) listFromFile: (NSString*)f;
/* Return the list of x509 certificates.
*/
- (gnutls_x509_crt_t*) certificateList;
/* Return number of certificates in list.
*/
- (unsigned int) count;
@end
/* This encapsulates private keys used to unlock certificates
@ -155,6 +162,8 @@ extern NSString * const GSTLSVerify;
asClient: (BOOL)client
debug: (BOOL)debug;
- (gnutls_certificate_credentials_t) credentials;
- (GSTLSPrivateKey*) key;
- (GSTLSCertificateList*) list;
- (BOOL) trust;
@end
@ -199,6 +208,14 @@ typedef ssize_t (*GSTLSIOW)(gnutls_transport_ptr_t, const void *, size_t);
*/
- (BOOL) active;
/* Returns the credentials object ofr this session.
*/
- (GSTLSCredentials*) credentials;
/* Return the current debug mode.
*/
- (BOOL) debug;
/* Disconnects and closes down the session.<br />
* The reusable flag specifies whether we intend to reuse the underlying
* connection.<br />

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: