Author: rfm Date: Fri Sep 2 09:59:08 2016 New Revision: 40067 URL: http://svn.gna.org/viewcvs/gnustep?rev=40067&view=rev Log: Add diagnostic code
Modified: libs/base/trunk/Resources/GSTLS/README libs/base/trunk/Source/GSTLS.h libs/base/trunk/Source/GSTLS.m Modified: libs/base/trunk/Resources/GSTLS/README URL: http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Resources/GSTLS/README?rev=40067&r1=40066&r2=40067&view=diff ============================================================================== --- libs/base/trunk/Resources/GSTLS/README (original) +++ libs/base/trunk/Resources/GSTLS/README Fri Sep 2 09:59:08 2016 @@ -5,7 +5,7 @@ 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 Modified: libs/base/trunk/Source/GSTLS.h URL: http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/GSTLS.h?rev=40067&r1=40066&r2=40067&view=diff ============================================================================== --- libs/base/trunk/Source/GSTLS.h (original) +++ libs/base/trunk/Source/GSTLS.h Fri Sep 2 09:59:08 2016 @@ -116,8 +116,15 @@ 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 @@ asClient: (BOOL)client debug: (BOOL)debug; - (gnutls_certificate_credentials_t) credentials; +- (GSTLSPrivateKey*) key; +- (GSTLSCertificateList*) list; - (BOOL) trust; @end @@ -199,6 +208,14 @@ */ - (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 /> Modified: libs/base/trunk/Source/GSTLS.m URL: http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/GSTLS.m?rev=40067&r1=40066&r2=40067&view=diff ============================================================================== --- libs/base/trunk/Source/GSTLS.m (original) +++ libs/base/trunk/Source/GSTLS.m Fri Sep 2 09:59:08 2016 @@ -716,14 +716,15 @@ [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 @@ { while (count-- > 0) { - gnutls_x509_crt_deinit(crts[count]); - } - free(crts); + if (crts) gnutls_x509_crt_deinit(crts[count]); + } + if (crts) free(crts); } } [super dealloc]; @@ -1193,7 +1194,7 @@ } } - /* 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 @@ return certcred; } +- (GSTLSPrivateKey*) key +{ + return key; +} + +- (GSTLSCertificateList*) list +{ + return list; +} + - (BOOL) trust { return trust; @@ -1269,7 +1280,83 @@ @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 @@ return active; } +- (GSTLSCredentials*) credentials +{ + return credentials; +} + - (void) dealloc { [self finalize]; @@ -1301,6 +1393,11 @@ DESTROY(credentials); DESTROY(problem); [super dealloc]; +} + +- (BOOL) debug +{ + return debug; } - (BOOL) disconnect: (BOOL)reusable @@ -1407,6 +1504,11 @@ 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 @@ @" 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 @@ 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 @@ 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 @@ 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); - - [str appendString: @"\n"]; - [str appendFormat: _(@"- Certificate %d info:\n"), cert_num]; - - [GSTLSCertificateList certInfo: cert to: str]; - - gnutls_x509_crt_deinit(cert); - } - } - } - break; + tmp = gnutls_certificate_type_get_name( + gnutls_certificate_type_get(session)); + [str appendFormat: _(@"- Authentication using certificate type: %s\n"), + tmp]; + + break; } /* switch */ if (ecdh != 0) @@ -1889,16 +1975,52 @@ 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 @@ [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 @@ /* 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: _______________________________________________ Gnustep-cvs mailing list Gnustep-cvs@gna.org https://mail.gna.org/listinfo/gnustep-cvs