From: Michael R Sweet Date: Tue, 24 Apr 2018 21:46:58 +0000 (-0400) Subject: Add issuer and signature algorithm to certificate string, show it in tlscheck output. X-Git-Tag: v2.3b5~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=073b3929a10175545417f1dc283980c36f3bff9e;p=thirdparty%2Fcups.git Add issuer and signature algorithm to certificate string, show it in tlscheck output. --- diff --git a/cups/tls-darwin.c b/cups/tls-darwin.c index 1192b86758..3e3a95daa8 100644 --- a/cups/tls-darwin.c +++ b/cups/tls-darwin.c @@ -800,24 +800,85 @@ httpCredentialsString( if ((first = (http_credential_t *)cupsArrayFirst(credentials)) != NULL && (secCert = http_cdsa_create_credential(first)) != NULL) { - CFStringRef cf_name; /* CF common name string */ - char name[256]; /* Common name associated with cert */ + /* + * Copy certificate (string) values from the SecCertificateRef and produce + * a one-line summary. The API for accessing certificate values like the + * issuer name is, um, "interesting"... + */ + + CFStringRef cf_string; /* CF string */ + CFDictionaryRef cf_dict; /* Dictionary for certificate */ + char commonName[256],/* Common name associated with cert */ + issuer[256], /* Issuer name */ + sigalg[256]; /* Signature algorithm */ time_t expiration; /* Expiration date of cert */ unsigned char md5_digest[16]; /* MD5 result */ - if ((cf_name = SecCertificateCopySubjectSummary(secCert)) != NULL) + if (SecCertificateCopyCommonName(secCert, &cf_string) == noErr) { - CFStringGetCString(cf_name, name, (CFIndex)sizeof(name), kCFStringEncodingUTF8); - CFRelease(cf_name); + CFStringGetCString(cf_string, commonName, (CFIndex)sizeof(commonName), kCFStringEncodingUTF8); + CFRelease(cf_string); } else - strlcpy(name, "unknown", sizeof(name)); + { + strlcpy(commonName, "unknown", sizeof(commonName)); + } + + strlcpy(issuer, "unknown", sizeof(issuer)); + strlcpy(sigalg, "UnknownSignature", sizeof(sigalg)); + + if ((cf_dict = SecCertificateCopyValues(secCert, NULL, NULL)) != NULL) + { + CFDictionaryRef cf_issuer = CFDictionaryGetValue(cf_dict, kSecOIDX509V1IssuerName); + CFDictionaryRef cf_sigalg = CFDictionaryGetValue(cf_dict, kSecOIDX509V1SignatureAlgorithm); + + if (cf_issuer) + { + CFArrayRef cf_values = CFDictionaryGetValue(cf_issuer, kSecPropertyKeyValue); + CFIndex i, count = CFArrayGetCount(cf_values); + CFDictionaryRef cf_value; + + for (i = 0; i < count; i ++) + { + cf_value = CFArrayGetValueAtIndex(cf_values, i); + + if (!CFStringCompare(CFDictionaryGetValue(cf_value, kSecPropertyKeyLabel), kSecOIDOrganizationName, kCFCompareCaseInsensitive)) + CFStringGetCString(CFDictionaryGetValue(cf_value, kSecPropertyKeyValue), issuer, (CFIndex)sizeof(issuer), kCFStringEncodingUTF8); + } + } + + if (cf_sigalg) + { + CFArrayRef cf_values = CFDictionaryGetValue(cf_sigalg, kSecPropertyKeyValue); + CFIndex i, count = CFArrayGetCount(cf_values); + CFDictionaryRef cf_value; + + for (i = 0; i < count; i ++) + { + cf_value = CFArrayGetValueAtIndex(cf_values, i); + + if (!CFStringCompare(CFDictionaryGetValue(cf_value, kSecPropertyKeyLabel), CFSTR("Algorithm"), kCFCompareCaseInsensitive)) + { + CFStringRef cf_algorithm = CFDictionaryGetValue(cf_value, kSecPropertyKeyValue); + + if (!CFStringCompare(cf_algorithm, CFSTR("1.2.840.113549.1.1.5"), kCFCompareCaseInsensitive)) + strlcpy(sigalg, "SHA1WithRSAEncryption", sizeof(sigalg)); + else if (!CFStringCompare(cf_algorithm, CFSTR("1.2.840.113549.1.1.11"), kCFCompareCaseInsensitive)) + strlcpy(sigalg, "SHA256WithRSAEncryption", sizeof(sigalg)); + else if (!CFStringCompare(cf_algorithm, CFSTR("1.2.840.113549.1.1.4"), kCFCompareCaseInsensitive)) + strlcpy(sigalg, "MD5WithRSAEncryption", sizeof(sigalg)); + } + } + } + + CFRelease(cf_dict); + } expiration = (time_t)(SecCertificateNotValidAfter(secCert) + kCFAbsoluteTimeIntervalSince1970); cupsHashData("md5", first->data, first->datalen, md5_digest, sizeof(md5_digest)); - snprintf(buffer, bufsize, "%s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", name, httpGetDateString(expiration), md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]); + snprintf(buffer, bufsize, "%s (issued by %s) / %s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", commonName, issuer, httpGetDateString(expiration), sigalg, md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]); CFRelease(secCert); } diff --git a/cups/tlscheck.c b/cups/tlscheck.c index b9af191d25..259e57248c 100644 --- a/cups/tlscheck.c +++ b/cups/tlscheck.c @@ -37,6 +37,8 @@ main(int argc, /* I - Number of command-line arguments */ http_t *http; /* HTTP connection */ const char *server = NULL; /* Hostname from command-line */ int port = 0; /* Port number */ + cups_array_t *creds; /* Server credentials */ + char creds_str[2048]; /* Credentials string */ const char *cipherName = "UNKNOWN";/* Cipher suite name */ int dhBits = 0; /* Diffie-Hellman bits */ int tlsVersion = 0; /* TLS version number */ @@ -154,6 +156,16 @@ main(int argc, /* I - Number of command-line arguments */ return (1); } + if (httpCopyCredentials(http, &creds)) + { + strlcpy(creds_str, "Unable to get server X.509 credentials.", sizeof(creds_str)); + } + else + { + httpCredentialsString(creds, creds_str, sizeof(creds_str)); + httpFreeCredentials(creds); + } + #ifdef __APPLE__ SSLProtocol protocol; SSLCipherSuite cipher; @@ -691,6 +703,8 @@ main(int argc, /* I - Number of command-line arguments */ else printf("%s: OK (TLS: %d.%d, %s)\n", server, tlsVersion / 10, tlsVersion % 10, cipherName); + printf(" %s\n", creds_str); + if (verbose) { httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipps", NULL, host, port, resource); @@ -714,6 +728,7 @@ main(int argc, /* I - Number of command-line arguments */ } ippDelete(response); + puts(""); } httpClose(http);